Tarjan模板题 The Bottom of a Graph

来源:互联网 发布:蓝月翅膀升级数据 编辑:程序博客网 时间:2024/06/08 17:57

题意:找出所有出度为0的连通分支
AC代码

#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<cstdio>#include<queue>#include<stack>#include<map>#include<stdlib.h>#include<set>#include<vector>using namespace std;#define CLR(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3f#define LL long long#define Pi acos(-1.0)#define EXP 1e-9#define up(i,x,y) for(int i=x;i<=y;i++)#define down(i,x,y) for(int i=x;i>=y;i--)#define w(x) while(x)#define Mod 1000000007struct node{    int next;    int v;}edge[50100];int dfn[50100];int low[50100];int head[50100];int astack[50100];int vis[50100];int astacknum=0;int cnt=0;int tot=0;int belongs[50100];int belongsnum=0;int a[50100];int b[50100];int out[50100];void add(int x,int y){    edge[++cnt].next=head[x];    edge[cnt].v=y;    head[x]=cnt;    return ;}void tarjan(int x){    dfn[x]=low[x]=++tot;    astack[++astacknum]=x;    vis[x]=1;    for(int i=head[x];i!=-1;i=edge[i].next){        if(!dfn[edge[i].v]){            tarjan(edge[i].v);            low[x]=min(low[x],low[edge[i].v]);        }        else if(vis[edge[i].v])            low[x]=min(low[x],dfn[edge[i].v]);    }    if(low[x]==dfn[x]){        belongsnum++;        do{            belongs[astack[astacknum]]=belongsnum;            vis[astack[astacknum]]=0;            astacknum--;        }while(x!=astack[astacknum+1]);    }    return ;}void init(){    CLR(dfn,0);    CLR(low,0);    CLR(out,0);    cnt=0;    tot=0;    CLR(belongs,0);    belongsnum=0;    CLR(astack,0);    astacknum=0;    CLR(vis,0);    CLR(head,-1);    return ;}int main(){    int v,e;    while(cin>>v){        if(v==0)            break;        cin>>e;        init();        for(int i=1;i<=e;i++){            cin>>a[i]>>b[i];            add(a[i],b[i]);        }        for(int i=1;i<=v;i++){            if(!dfn[i]) tarjan(i);        }        for(int i=1;i<=e;i++){            if(belongs[a[i]]!=belongs[b[i]]){                out[belongs[a[i]]]++;            }        }        int flag=0;        for(int i=1;i<=v;i++){            if(out[belongs[i]]==0){                if(!flag){                    cout<<i;                    flag=1;                }                else                    cout<<" "<<i;            }        }        cout<<endl;    }    return 0;}