题解:根据环的性质,可以去掉入度为0的点后拓扑排序或直接搜(因为懒,代码中没有去掉而是加标记防止算上其他环上的点)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int M=200005;
#define INF 0x3f3f3f3f
struct edge{
int to,next;
}e[M];
int head[M],vis[M],dr[M];
int n,ans=INF,x,t;
void add(int i,int j)
{
e[t].to=j;
e[t].next=head[i];
head[i]=t++;
}
void init()
{
memset(head,-1,sizeof(head));
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&x),add(i,x);
}
void dfs(int x,int tm,int size)
{
vis[x]=tm;
for(int i=head[x];i!=-1;i=e[i].next){
int v=e[i].to;
if(!vis[v]) dr[v]=size,dfs(v,tm,size+1);
else if(vis[v]==tm) {
ans=min(ans,size-dr[v]);
return ;
}
}
}
void work()
{
for(int i=1;i<=n;i++)
if(!vis[i]) dfs(i,i,1);
cout<<ans<<endl;
}
int main()
{
init();
work();
return 0;
}