• 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("
    ");
            if(flag==0)
                printf("
    ");
                //printf("scc %d
    ",scc);
            
        }
        return 0;
    }
  • 相关阅读:
    mock数据
    关于适配各种浏览器的图片预览。
    闭包
    兼容性 适配
    递归 使用callee
    webservice的model层命名空间不同的问题
    删除右键菜单中的Git
    windows server core 设置shell 及切换
    设置共享用户名密码
    Windows Remote Shell(WinRM)使用介绍
  • 原文地址:https://www.cnblogs.com/assult/p/3237888.html
Copyright © 2020-2023  润新知