读书人

The Bottom of a Graph 强接通分量加缩

发布时间: 2012-08-30 09:55:54 作者: rapoo

The Bottom of a Graph 强连通分量加缩点

/*题意比较晦涩,大致就是求一个图缩点后出度为0的点的个数。*/#include <stdio.h>#include <cstring>#include <vector>#include <iostream>using namespace std;vector<int> e[5010];int dfn[5001];int low[5001];int stack[5001];bool instack[5001];int belong[5001];int out[5001];int n,m,num,top,cnt;void tarjan(int u){    int j;    stack[top++]=u;    low[u]=dfn[u]=++num;    instack[u]=true;    for(int i=0; i<e[u].size(); i++)    {        int v=e[u][i];        if(!dfn[v])        {            tarjan(v);            low[u]=min(low[v],low[u]);        }        else if(instack[v])            low[u]=min(dfn[v],low[u]);    }    if(low[u]==dfn[u])    {        cnt++;        do        {            j=stack[--top];            instack[j]=false;            belong[j]=cnt;        }        while(j!=u);    }}int main(){    while(scanf("%d",&n)==1)    {        if(n==0) break;        scanf("%d",&m);        int a,b;        for(int i=1; i<=n; i++)            e[i].clear();        top=0;        num=0;        cnt=0;        while(m--)        {            scanf("%d%d",&a,&b);            e[a].push_back(b);        }        memset(low,0,sizeof(low));        memset(dfn,0,sizeof(dfn));        memset(instack,false,sizeof(instack));        memset(belong,0,sizeof(belong));        for(int i=1; i<=n; i++)        {            out[i]=0;            if(!dfn[i])                tarjan(i);        }        for(int i=1; i<=n; i++)        {            int len=e[i].size();            for(int j=0; j<len; j++)            {                if(belong[i]!=belong[e[i][j]])                    out[belong[i]]++;            }        }        int k=0;        for(int i=1; i<=n; i++)        {            if(out[belong[i]]==0)            {                if(k++) printf(" ");                printf("%d",i);            }        }        printf("\n");    }    return 0;}

 

读书人网 >编程

热点推荐