zoukankan      html  css  js  c++  java
  • poj 2186 Popular Cows【tarjan求scc个数&&缩点】【求一个图中可以到达其余所有任意点的点的个数】

    Popular Cows
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 27698   Accepted: 11148

    Description

    Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is 
    popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow. 

    Input

    * Line 1: Two space-separated integers, N and M 

    * Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular. 

    Output

    * Line 1: A single integer that is the number of cows who are considered popular by every other cow. 

    Sample Input

    3 3
    1 2
    2 1
    2 3
    

    Sample Output

    1
    

    Hint

    Cow 3 is the only cow of high popularity. 
    题意:有n头牛,已知m个关系即牛a认为牛b是受欢迎,现在问你在n头牛里有多少头牛被 除它外所有的牛认为是受欢迎的。
    题解:
    一:出度为0的SCC有0个,显然易见,该图就是一个强连通图,所有牛都满足条件;
    二:出度为0的SCC有1个,满足条件的只有这一个SCC里面的牛;
    三:出度为0的SCC超过1个,无论如何,出度超过0的SCC之间是无法连通的,所以没有牛满足。
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #define MAX 50010
    #define INF 0x3f3f3f
    using namespace std;
    struct node
    {
        int beg,end,next;
    }edge[MAX];
    int low[MAX],dfn[MAX];
    int n,m,ans;
    int sccno[MAX],instack[MAX];
    int dfsclock,scccnt;
    vector<int>newmap[MAX];
    vector<int>scc[MAX];
    int head[MAX];
    int out[MAX];
    stack<int>s;
    int sum,sumout,ant;
    void init()
    {
        ans=0;
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v)
    {
        edge[ans].beg=u;
        edge[ans].end=v;
        edge[ans].next=head[u];
        head[u]=ans++;
    }
    void getmap()
    {
        int a,b,i;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            add(a,b);
        }
    }
    void tarjan(int u)
    {
        int v,i,j;
        s.push(u);
        instack[u]=1;
        dfn[u]=low[u]=++dfsclock;
        for(i=head[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].end;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(instack[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            scccnt++;
            while(1)
            {
                v=s.top();
                s.pop();
                instack[v]=0;
                sccno[v]=scccnt;
                if(v==u)
                break;
            }
        }
    }
    void find(int l,int r)
    {
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(instack,0,sizeof(instack));
        memset(sccno,0,sizeof(sccno));
        dfsclock=scccnt=0;
        for(int i=l;i<=r;i++)
        {
            if(!dfn[i])
                tarjan(i);
        }
    }
    void suodian()
    {
        int i;
        ant=0;
        for(i=1;i<=scccnt;i++)
        {
            newmap[i].clear();
            out[i]=0;
        }
        for(i=0;i<ans;i++)
        {
            int u=sccno[edge[i].beg];
            int v=sccno[edge[i].end];
            if(u!=v)
            {
                newmap[u].push_back(v);
                out[u]++;
            }
        }
    }
    void solve()
    {
        int i,j;
    	sumout=0;sum=0;
    	for(i=1;i<=scccnt;i++)
    	{
    		if(!out[i])
    		{
    			sumout++;
    			ant=i;
    		}
    	}
    	if(sumout==0)
    	{
    		printf("%d
    ",n);
    		return ;
    	}
        else if(sumout==1)
        {
        	for(i=1;i<=n;i++)
        	    if(sccno[i]==ant)
        	        sum++;
        	printf("%d
    ",sum); 
        }
    	else 
    	printf("0
    ");
    }
    int main()
    {
        int t;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            getmap();
            find(1,n);
            suodian();
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    PAT (Basic Level) Practice 1020 月饼 (25分)
    PAT (Basic Level) Practice 1019 数字黑洞 (20分) (string、int转换+sort排序)
    PAT (Basic Level) Practice 1018 锤子剪刀布 (20分) (三个数比大小)
    PAT (Basic Level) Practice 1017 A除以B (20分) (大数除法+大神简洁20行代码)
    PAT (Basic Level) Practice 1016 部分A+B (15分)
    PAT (Basic Level) Practice 1015 德才论 (25分) (大量IO的节省时间)
    PAT (Basic Level) Practice 1014 福尔摩斯的约会 (20分) (string的find函数中没查找到返回s.npos)
    PAT (Basic Level) Practice (中文) 1013 数素数 (20分)
    XSY1762
    XSY1602
  • 原文地址:https://www.cnblogs.com/tonghao/p/4823588.html
Copyright © 2011-2022 走看看