给定 n 个人,每个人可以连上一个人建一条单向边,构成一个有向有环图,求最小环
输出样例
3
Tarjan扫一遍过
code
#include<stdio.h>
#include<algorithm>
using namespace std;
const int MX=200001;
struct Edge {
int to,next;
}edge[MX];
int n,k,cnt,top,idx,low[MX],dfn[MX],first[MX],stk[MX];
int ans=MX;
void add(int from,int to)
{
edge[++cnt].to=to;
edge[cnt].next=first[from];
first[from]=cnt;
}
void Tarjan(int x)
{
stk[++top]=x;
dfn[x]=low[x]=++idx;
for(int i=first[x];i;i=edge[i].next) {
int to=edge[i].to;
if(!dfn[to]) {
Tarjan(to);
low[x]=min(low[x],low[to]);
}
else low[x]=min(low[x],dfn[to]);
}
if(low[x]==dfn[x]) {
int d,len=0;
do {
d=stk[top--];
len++;
}while(d!=x);
if(len!=1)
ans=min(ans,len);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) {
int poi;scanf("%d",&poi);
add(i,poi);
}
for(int i=1;i<=n;++i) if(!dfn[i]) Tarjan(i);
printf("%d",ans);
return 0;
}