POJ2186 Tarjan强连通分量+缩点

来源:互联网 发布:打卡网络用语什么意思 编辑:程序博客网 时间:2024/05/01 00:52

这道题基于Tarjan的求强连通分量,然后缩点

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <stack>using namespace std;struct EDGE{    int v;    int next;}edge[55555];int head[11111],low[11111],dfn[11111],id[11111],out[11111],ans[11111];int e,depth,cnt,n,m;stack <int> q;void addedge(int u,int v){    edge[e].v = v;    edge[e].next = head[u];    head[u] = e++;}void dfs(int x){    low[x] = dfn[x] = ++depth;    q.push(x);    for(int i = head[x] ; i != -1 ; i = edge[i].next){        int v = edge[i].v;        if(!dfn[v]){            dfs(v);            low[x] = min(low[v],low[x]);        }        else if(!id[v]){            low[x] = min(dfn[v],low[x]);        }    }    if(low[x] == dfn[x]){        cnt++;        int temp = 0;        int v;        do{            temp++;            v = q.top();            q.pop();            id[v] = cnt;        }while(v != x);        ans[cnt] = temp;    }    return ;}void Tarjan(){    cnt = depth = 0;    while(!q.empty()){        q.pop();    }    memset(dfn,0,sizeof(dfn));    for(int i = 1 ; i <= n ; i ++){        if(!dfn[i])            dfs(i);    }    return ;}void init(){    e = 0;    memset(id,0,sizeof(id));    memset(head,-1,sizeof(head));    memset(out,0,sizeof(out));}int main(){    while(scanf("%d%d",&n,&m) != EOF){        init();        for(int i = 0 ; i < m ; i ++){            int a,b;            scanf("%d%d",&a,&b);            addedge(a,b);        }        Tarjan();        if(cnt == 1){            printf("%d\n",n);            continue;        }        for(int i = 1 ; i <= n ; i ++){            for(int j = head[i] ; j != -1 ; j = edge[j].next){                int v = edge[j].v;                if(id[i] != id[v]){                    out[id[i]]++;                }            }        }        int res = 0;        for(int i = 1 ; i <= cnt ; i ++){            if(!out[i]){                if(!res){                    res = ans[i];                }                else                {                    res = 0;                    break;                }            }        }        printf("%d\n",res);    }    return 0;}


原创粉丝点击