问题描述
有n个同学(编号为1到n)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?
三倍经验?
只要找出最小环的大小就可以,看见题解里有很多拓扑排序的,还有用tarjan的,我用了一个dfs树,如果有返祖的就记录最小的深度。
其他两种做法我还会回来补充上(大概)
DFS树
#include<bits/stdc++.h> using namespace std; int n,ans=200000000; int to[200005],num[200005],dep[200005],tot; void dfs(int x,int d){ dep[x]=d; num[x]=tot; if(dep[to[x]]){ if(num[to[x]]!=tot)return ; else ans=min(ans,d-dep[to[x]]+1); } else dfs(to[x],d+1); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&to[i]); } for(int i=1;i<=n;i++){ if(!dep[i]){ tot=i; dfs(i,1); } } printf("%d",ans); }