题目链接:洛谷 P2661 信息传递
一个人要想知道自己的生日,就意味着信息的传递是成环的,因为每轮信息只能传递一个人,传递的轮数就等于环的大小
环的大小就等于环中的两个点到第三个点的距离之和加一,我们就可以在使用并查集时,维护每个点到某个确定点的距离
不妨令这个确定点为当前点的祖先,在同一个集合中,所有的点拥有共同的祖先,因此可以确定环的大小
有可能有多个环,最小的环就是最小的轮数
1 #include <bits/stdc++.h> 2 using namespace std; 3 int f[200005]; 4 int l[200005]; //到祖先的距离 5 int minn = 1<<30; 6 7 int fa(int a){ 8 if(f[a] != a){ 9 int father = f[a]; 10 f[a] = fa(f[a]); 11 l[a] += l[father]; 12 } 13 return f[a]; 14 } 15 16 bool check(int a,int b){ 17 return fa(a) == fa(b); 18 } 19 20 void link(int a,int b){ 21 if(!check(a,b)){ 22 f[fa(a)] = fa(b); 23 l[a] = l[b]+1; 24 } 25 else //已经成环 26 minn = min(minn,l[a]+l[b]+1); 27 } 28 29 int main() 30 { 31 int n; 32 cin>>n; 33 for(int i=1;i<=n;++i) 34 f[i] = i; 35 for(int i=1;i<=n;++i){ 36 int ans; 37 cin>>ans; 38 link(i,ans); 39 } 40 cout<<minn; 41 return 0; 42 }