信息传递
Description
有 n 个同学(编号为 1 到 n )正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为 的同学的信息传递对象是编号为
的同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息, 但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自 己的生日时,游戏结束。请问该游戏一共可以进行几轮?
Input
共2行。
第1行包含1个正整数 n ,表示 n 个人。
第2行包含 n 个用空格隔开的正整数 ,其中第
个整数
表示编号为
的同学的信息传递对象是编号为
的同学,
且
i。
Output
1个整数,表示游戏一共可以进行多少轮。
Sample Input
5
2 4 2 3 1
Sample Output
3
Solution
并查集找最小环。
Code
#include<iostream>
#include<cmath>
using namespace std;
#define N 400001
struct union_Find_Sets{
int fa[N],dis[N];
int findFa(int v){
if(fa[v]!=v){
int f=fa[v];
fa[v]=findFa(fa[v]);
dis[v]+=dis[f];
}
return fa[v];
}
int query(int v,int u){
int fx=findFa(v),fy=findFa(u);
if(fx!=fy){
fa[fx]=fy;
dis[v]=dis[u]+1;
return 0x7ffffff;
}
else return dis[v]+dis[u]+1;
}
void init(int size){
for(int i=1;i<=size;i++){
fa[i]=i;
}
}
}ufs;
int n,minn=0x7ffffff;
int main(){
cin>>n;
ufs.init(n);
for(int i=1;i<=n;i++){
int t;
cin>>t;
minn=min(minn,ufs.query(i,t));
}
cout<<minn;
}