The Bottom of a Graph 强连通分量 缩点后 那些点的出度为0

http://poj.org/problem?id=2553

 

#include<iostream>
#include<stdio.h>
//#include<vector>
#include<string.h>
#include<stack>
using namespace std;
//vector <int > g[1002];
struct E{int to;int next;} edge[20000000];
int pre[5002],low[5002],lt_num,c,scc_num[5002],scc,out0[5002],n,adj[5002],num,flag;

stack <int >s;
void add(int a,int b)
{
    edge[num].to=b;
    edge[num].next=adj[a];
    adj[a]=num++;
}
void dfs(int u)    //  求出每个点的强连通分量标号
{
    int i,v;
    pre[u]=low[u]=c++;
    s.push (u);
    for(i=adj[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].to;
        if(!pre[v])//!scc_num[v]
        {
            dfs(v);
            if(low[v]<low[u])
                low[u]=low[v];
        }
        else if(low[v]<low[u]&&!scc_num[v])
            low[u]=low[v];
    }
    if(low[u]==pre[u])   //是该连通分量的 第一个点
    {
        scc++;
        while(1)
        {
            int t=s.top ();s.pop ();
            scc_num[t]=scc;             //scc_num[t]是第scc个强连通分量;
            if(t==u)
                break;
        }
    }
}

void solve()
{
    int i,j,v; 
    memset(out0,0,sizeof(out0));
    for(i=1;i<=n;i++)
        for(j=adj[i];j!=-1;j=edge[j].next)
        {
            v=edge[j].to;
            if(scc_num[i]!=scc_num[v])
                out0[scc_num[i]]=1;
        }
        for(i=1;i<=n;i++)
            if(!out0[scc_num[i]])  // 缩点后的 出度为0的 点
            {
                flag=1;
                printf("%d ",i);
            }
}


int main()
{
    int i,m,a,b;
    while(scanf("%d",&n))
    {
        flag=0;
        if(n==0)
            break;
        scanf("%d",&m);
            memset(adj,-1,sizeof(adj));
        while(m--)
        {
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        scc=0;c=1;num=0;                 //  注意c一定不能从0开始
        memset(pre,0,sizeof(pre));
    
        memset(scc_num,0,sizeof(scc_num));
        for(i=1;i<=n;i++)
            if(!pre[i])
                dfs(i);
            solve();
            
        printf("\n");
        if(flag==0)
            printf("\n");
            //printf("scc %d\n",scc);
        
    }
    return 0;
}

 

posted @ 2013-08-05 11:48  galaxy77  阅读(164)  评论(0编辑  收藏  举报