某校科技节到了,有𝑛 个同学(编号为1到𝑛)正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为𝑖 的同学的信息传递对象是编号为𝑇𝑖的同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?
解
𝑛≤200000。DFS模拟会炸空间,所以用while和queue。
代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<queue>
using namespace std;
int b[200005], f[200005], ans, n, to[200005], t;
int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
queue<int> Q;
scanf("%d", &n);
ans = n;
for(int i = 1; i <= n; ++i)
scanf("%d", &to[i]);
for(int i = 1; i <= n; ++i)
if(b[i] == 0){
Q.push(i);
int deep = 1;
++t;
while(1){
int d = Q.front();
Q.pop();
b[d] = deep; //记录深度
f[d] = t; //记录环)?
if(b[to[d]] == 0) Q.push(to[d]), ++deep; //没去过
else{
if(f[to[d]] == t) //同一个环里的...
ans = min(ans, deep - b[to[d]] + 1); //这个环的长度
break; //不存在环,不会得知自己生日
}
}
}
printf("%d", ans);
fclose(stdin);
fclose(stdout);
}