题目描述
有 nn个同学(编号为 11 到 nn )正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为 ii 的同学的信息传递对象是编号为 TiTi 的同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息, 但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自 己的生日时,游戏结束。请问该游戏一共可以进行几轮?
输入输出格式
输入格式:
共 22 行。
第 11 行包含11个正整数 nn ,表示 nn 个人。 第 22 行包含 nn 个用空格隔开的正整数 T1,T2,.....,TnT1,T2,.....,Tn ,其中第 ii 个整数 T_i 表示编号为 ii的同学的信息传递对象是编号为TiTi 的同学, Ti≤n且Ti≠iTi≤n且Ti≠i输出格式:
1 个整数,表示游戏一共可以进行多少轮。
输入输出样例
输入样例#1:
5
2 4 2 3 1输出样例#1:
3
说明 样例1解释游戏的流程如图所示。当进行完第 33 轮游戏后, 4 4 号玩家会听到 22 号玩家告诉他自己的生日,所以答案为 33 。当然,第 33 轮游戏后, 2 2 号玩家、 33 号玩家都能从自己的消息来源得知自己的生日,同样符合游戏结束的条件。
对于 3030 的数据, n≤200;n≤200;
对于 6060 的数据,n≤2500;n≤2500;
对于 100100 的数据, n≤200000。n≤200000。
#includeusing namespace std;const int MAXN=2e5+10;struct node{ int v; int next;}edge[MAXN*10];int head[MAXN*10];bool Vis[MAXN];int cnt;int dfn[MAXN],low[MAXN];void add(int x,int v){ edge[++cnt].v =v; edge[cnt].next=head[x]; head[x]=x;}int Time;int ans=0x3f3f3f3f;stack st;int num=0;void tarjan(int u){ dfn[u]=low[u]=++Time; st.push(u); Vis[u]=true; for (int i = head[u]; i!=-1 ; i=edge[i].next) { int v=edge[i].v; if(!dfn[v]){ tarjan(v); low[u]=min(low[v],low[u]); } else if(Vis[v]){ low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]){ int x; num=0; while(1) { x=st.top(); st.pop(); num++; Vis[x]= false; if(x==u) break; } if(num>1) ans=min(ans,num); }}int read(){ int x=0,f=1; char ch; for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-f; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0'; return x*f;}int main(){// freopen("E:\\testdata.in","r",stdin); int n; n=read(); int x; for (int j = 1; j <=n ; ++j) { head[j]=-1; } for (int i = 1; i <=n ; ++i) { x=read(); add(i,x); } for (int i = 1; i <=n ; ++i) { if(dfn[i]==0) tarjan(i); } printf("%d\n",ans); return 0;}