poj 2553 tarjan

来源:互联网 发布:雄猫软件培训骗局 编辑:程序博客网 时间:2024/05/29 19:52

求一个图出度为0的强连通分量。

#include <iostream>#include <cstdio>#include <cstring>const int maxn=5500;using namespace std;struct{    int to,next;}e[maxn*maxn];int head[maxn],lon;void edgeini(){    memset(head,-1,sizeof(head));    lon=-1;}void edgemake(int from,int to){    e[++lon].to=to;    e[lon].next=head[from];    head[from]=lon;}int dfn[maxn],low[maxn],stack[maxn],cnt,chk[maxn],top,ans[maxn],mm,f[maxn];void tarjan(int t){    low[t]=dfn[t]=++cnt;    stack[++top]=t;    chk[t]=1;    for(int k=head[t];k!=-1;k=e[k].next)    {        int u=e[k].to;        if(dfn[u]==-1)        {            tarjan(u);            low[t]=min(low[t],low[u]);        }        else if(chk[u])        {            low[t]=min(low[t],dfn[u]);        }    }    if(low[t]==dfn[t])    {        ++mm;        while(stack[top]!=t)        {            f[stack[top]]=mm;            chk[stack[top--]]=0;        }        f[t]=mm;        chk[t]=0;        top--;    }}int main(){//    freopen("in.txt","r",stdin);    int n,m;    while(scanf("%d",&n),n)    {        edgeini();        scanf("%d",&m);        for(int i=1,from,to;i<=m;i++)        {            scanf("%d %d",&from,&to);            edgemake(from,to);        }        mm=top=cnt=0;        memset(dfn,-1,sizeof(dfn));        memset(chk,0,sizeof(chk));        memset(f,0,sizeof(f));        for(int i=1;i<=n;i++)        if(dfn[i]==-1)        tarjan(i);        for(int i=1;i<=n;i++) ans[i]=1;        for(int i=1;i<=n;i++)        for(int k=head[i];k!=-1;k=e[k].next)        {            if(f[i]!=f[e[k].to])            ans[f[i]]=0;        }        for(int i=1,tt=1;i<=n;i++)        {            if(ans[f[i]])            {                if(tt)                {                    printf("%d",i);                    tt=0;                }                else                printf(" %d",i);            }        }        printf("\n");    }    return 0;}


原创粉丝点击