zoukankan      html  css  js  c++  java
  • poj2186 Popular Cows --- 强连通

    给一个有向图,问有多少结点是其它全部结点都能够到达的。

    等价于,在一个有向无环图上,找出度为0 的结点。假设出度为0的结点仅仅有一个,那么这个就是答案。假设大于1个。则答案是0。

    这题有环。所以先缩点。

    求唯一出度为0的强连通分量。


    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<iostream>
    #define inf 0x3f3f3f3f
    using namespace std;
    #define M 10010//图中点数
    int sta[M],top;
    bool vis[M];
    int dfn[M];
    int low[M];
    int ccnt;        //有向图强连通分量个数
    int id;
    vector<int> e[M];
    vector<int> part[M];//每一个联通块的组成
    int inpart[M];//每一个原图上的点在哪个联通块里
    int n,m,out[M];
    
    void tarjan(int x)
    {
        int i,j;
        dfn[x]=low[x]=id++;
        vis[x]=1;
        sta[++top]=x;
        for(i=0;i<e[x].size();i++)
        {
            j=e[x][i];
            if(dfn[j]==-1)
            {
                tarjan(j);
                low[x]=min(low[x],low[j]);
            }
            else if(vis[j])
                low[x]=min(low[x],dfn[j]);
        }
        if(dfn[x]==low[x])
        {
            do
            {
                j=sta[top--];
                vis[j]=0;
                part[ccnt].push_back(j);
                inpart[j]=ccnt;
            }while(j!=x);
            ccnt++;
        }
    }
    
    void solve(int n)
    {
        memset(sta,-1,sizeof sta);
        memset(vis,0,sizeof vis);
        memset(dfn,-1,sizeof(dfn));
        memset(low,-1,sizeof(low));
        top=ccnt=id=0;
        for(int i=1;i<=n;i++)
            if(dfn[i]==-1)
                tarjan(i);
    }
    
    int main()
    {
        int i,j,a,b,c;
        while(~scanf("%d%d",&n,&m))
        {
            for(i=0;i<=n;i++)
            {
                part[i].clear();
                e[i].clear();
            }
            while(m--)
            {
                scanf("%d%d",&a,&b);
                e[a].push_back(b);
            }
            solve(n);
            memset(out,0,sizeof out);
            for(i=1;i<=n;i++)
            {
                for(j=0;j<e[i].size();j++)
                {
                    a=e[i][j];
                    if(inpart[a]!=inpart[i])
                        out[inpart[i]]++;
                }
            }
            int ans=0,flag=0;
            for(i=0;i<ccnt;i++)
            {
                if(out[i]==0)
                {
                    flag++;
                    ans+=part[inpart[i]].size();
                }
                if(flag>1)//大于一个出度为0的点 则没有符合条件的答案
                {
                    ans=0;
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    180602-nginx多域名配置
    180601-MySql性能监控工具MyTop
    180530-反射获取泛型类的实际参数
    180531-Spring中JavaConfig知识小结
    RabbitMQ基础教程之Spring&JavaConfig使用篇
    RabbitMQ基础教程之使用进阶篇
    RabbitMQ基础教程之基本使用篇
    jquery控制文字内容溢出用点点点(…)省略号表示
    用CSS设置Table的细边框的最好用的方法
    web app 自适应方案总结 弹性布局之rem
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5210940.html
Copyright © 2011-2022 走看看