hdu 3594 强连通好题仙人掌图,对自己的tarjan模板改下用这个

#include<stdio.h>
#include<string.h>
#define N 21000
struct node {
int v,next;
}bian[51000];
int yong,dfn[N],low[N],stac[N],top,index,visit[N],ans,flag,mark[N],head[N],pre[N];
void init() {//初始化
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(mark,0,sizeof(mark));
memset(visit,0,sizeof(visit));
memset(head,-1,sizeof(head));
memset(pre,0,sizeof(pre));
flag=0;yong=0;
index=0;top=0;ans=0;
memset(stac,0,sizeof(stac));
}
void addedge(int u,int v) {
bian[yong].v=v;
bian[yong].next=head[u];
head[u]=yong++;
}
int MIN(int a,int b) {
return a>b?b:a;
}
void judge(int v,int u) {//对于每一个强连通分量对边的两边的点增一
while(pre[u]!=v) {
    mark[u]++;
    if(mark[u]>1) {
        flag=1;return ;
    }
    u=pre[u];
}
return ;
}
void tarjan(int u) {
 dfn[u]=low[u]=++index;
 stac[++top]=u;
 visit[u]=1;
 int i;
 for(i=head[u];i!=-1;i=bian[i].next) {
    int v=bian[i].v;
    if(dfn[v]==0) {
        pre[v]=u;
        tarjan(v);
        if(flag)
            return ;
      low[u]=MIN(low[u],low[v]);
    }
    else if(visit[v]) {
        judge(v,u);
        if(flag)return ;
        low[u]=MIN(low[u],dfn[v]);
    }
 }
 if(dfn[u]==low[u]) {
    ans++;
    if(ans>1){//判断是否是一个强联通图
        flag=1;return ;
    }
    int t;
    do{
        t=stac[top--];
        visit[t]=0;
    }while(t!=u);
 }
 return ;
}
int main() {
      int t,n,a,b,i;
      scanf("%d",&t);
      while(t--) {
            init();
        scanf("%d",&n);
        while(scanf("%d%d",&a,&b),a||b) {
            addedge(a,b);
        }
        for(i=0;i<n;i++) {
                if(!dfn[i])
            tarjan(i);
        if(flag)break;
        }
        if(flag==0)
            printf("YES
");
        else
            printf("NO
");
      }
return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410708.html