其他分享
首页 > 其他分享> > 洛谷 P2661 信息传递

洛谷 P2661 信息传递

作者:互联网

图论入门题

首先分析一下题目。不妨把图画出来:

可以看到,2,3,4由于在一个环中,三轮游戏过后,他们都会拿到自己的信息。

于是乎,题目实际上要求我们求图中的最小环

因为我们只需要在环上的点。所以不妨先删除所有不在环上的点,具体做法就是删除入度为0的点和他的出边,如果他连到的点的入度也为0,那把那个点和其出边也删除。类似于拓扑排序。

最后求出每个环的长度即可。具体见代码:

#include<bits/stdc++.h>
using namespace std;
int n,t[200010],ans=2000000,r[200010],mark[200010];
queue<int> q;
void dfs(int start,int now,int l){//start表示从那个点开始,now表示现在在哪,l记录环的长度
    if(now==start && l!=0){//绕了一圈回来了
        ans=min(l,ans);
        return ;
    }
    if(mark[t[now]]==0){
        mark[t[now]]=-1;
        dfs(start,t[now],l+1); 
    }
}
void clean(int i){
    r[t[i]]--;
    mark[i]=-1;
    if(r[t[i]]==0 && mark[t[i]]==0){
        clean(t[i]);
    }
}
int main(){
    freopen("1.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&t[i]); 
        r[t[i]]++;//计算每个点的入度 
    }
    for(int i=1;i<=n;i++){
        if(r[i]==0 && mark[i]==0){
            clean(i);
        }
    }
    for(int i=1;i<=n;i++){
        if(mark[i]==0){//如果一个点所在的环没有被遍历过 
            dfs(i,i,0);
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

标签:洛谷,P2661,int,mark,传递,start,ans,now,200010
来源: https://www.cnblogs.com/Laehcim/p/10802443.html