由题意得,只有强连通分量之间传递才能最终得到自己的编号。
可以用(tarjan)找出强连通分量,并从中找出大于1的最小的强连通分量则是最小的游戏回合数
//AC代码
//找SCC
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<stack>
#define N 200010
using namespace std;
int n;
int Root[N],Next[N],v[N],cnt;
int scc[N],scccnt,dfn[N],low[N],dfscnt;
int ans[N];
stack<int>st;
inline void add(int _u,int _v)
{
v[++cnt]=_v;
Next[cnt]=Root[_u];
Root[_u]=cnt;
}
inline void tarjan(int u){
dfn[u]=low[u]=++dfscnt;
st.push(u);
for(int x=Root[u];x!=0;x=Next[x]){
if(!dfn[v[x]]){
tarjan(v[x]);
low[u]=min(low[u],low[v[x]]);
}
else if(!scc[v[x]]) low[u]=min(low[u],dfn[v[x]]);
}
int t;
if(low[u]==dfn[u]){
scccnt++;
do{
t=st.top(); st.pop();
scc[t]=scccnt,ans[scccnt]+=1;
}while(t!=u);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
int V;scanf("%d",&V);
add(i,V);
}
for(int i=1;i<=n;++i)
if(!dfn[i])tarjan(i);
int Min=0x3f3f3f3f;
for(int i=1;i<=n;++i){
if(ans[i]>1)Min=min(Min,ans[i]);
}
printf("%d",Min);
return 0;
}