[图论]求最小环的长度

信息传递

Description

有 nn 个同学(编号为 11 到 nn )正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为 ii 的同学的信息传递对象是编号为 T_iTi 的同学。

游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息, 但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自 己的生日时,游戏结束。请问该游戏一共可以进行几轮?

Input

2行。

1行包含1个正整数 n ,表示 n 个人。

2行包含 n 个用空格隔开的正整数 T1,T2,,Tn ,其中第 i 个整数 Ti 表示编号为 i 的同学的信息传递对象是编号为 Ti 的同学, Tn 且 Tii 。

Output

1个整数,表示游戏一共可以进行多少轮。

Examples

Input

5
2 4 2 3 1

Output

3

 

正确解法:

很容易画出一个有向图,后来想一想,如何传递这个生日。

走一轮一条边,走出一个环的长度,游戏结束了。

那么这题所要求的就是最小环的长度。

一个图如何求最小环的长度呢?

从每个点的出度开始求,如果找了半天最终发现他的父亲就是他自己,那么这是一个环。长度就在递归的次数。

容易坑的一个点就是有一个 & 符号。目前为什么我还没有想出来qaq

 1  for(int i=1;i<=n;i++)
 2     {
 3         int xx;
 4         cnt=0;
 5         scanf("%d",&xx);
 6         if(getf(xx,cnt)==i)
 7             ans=min(ans,cnt);
 8         else
 9             fa[i]=xx;
10     }
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<map>
 6 #include<set>
 7 #include<vector>
 8 #include<queue>
 9 #include<algorithm>
10 #include<cmath>
11 using namespace std;
12 typedef long long ll;
13 const int N=200000+10;
14 int n,fa[N],cnt;
15 int ans=99999999;
16 int getf(int x,int &cnt)
17 {
18     cnt++;
19     if(fa[x]==x)    return x;
20     return getf(fa[x],cnt);
21 }
22 int main()
23 {
24     scanf("%d",&n);
25     for(int i=1;i<=n;i++)
26         fa[i]=i;
27     for(int i=1;i<=n;i++)
28     {
29         int xx;
30         cnt=0;
31         scanf("%d",&xx);
32         if(getf(xx,cnt)==i)
33             ans=min(ans,cnt);
34         else
35             fa[i]=xx;
36     }
37     printf("%d\n",ans);
38     return 0;
39 }
View Code

 

posted @ 2019-03-02 12:55  kaike  阅读(943)  评论(0编辑  收藏  举报