信息传递(luogu 2661)

-->测评传送门

给定 n 个人,每个人可以连上一个人建一条单向边,构成一个有向有环图,求最小环
 
输入样例
5
2 4 2 3 1
输出样例
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;
}

猜你喜欢

转载自www.cnblogs.com/qseer/p/9747027.html