POJ 2186 Popular Cows(tarjan缩点)

来源:互联网 发布:jquery.form.js用法 编辑:程序博客网 时间:2024/05/21 17:23

Popular Cows
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 35131 Accepted: 14323

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 31 22 12 3

Sample Output

1

Hint

Cow 3 is the only cow of high popularity. 

Source

USACO 2003 Fall

题意:

每个牛都有欣赏的牛,且可以专递欣赏。求被所以其他牛欣赏的牛的数量。

POINT:

tarjan缩点,把环化为一个点。接着就是有向无环图。求出度为0的点数,若大于1,则不存在。

反之则输出这个点数所代表强连通分量的数量。(单个点也是强连通分量)

#include <iostream>#include <stdio.h>#include <stack>#include <vector>using namespace std;#define  LL long longconst int maxn = 50100;vector<int>G[maxn];int DFN[maxn],low[maxn],color[maxn],instack[maxn];int num[maxn],cornum,tm;int n,m;stack<int> q;void tarjan(int u){    DFN[u]=low[u]=++tm;    instack[u]=1;    q.push(u);    for(int i=0;i<G[u].size();i++)    {        int v=G[u][i];        if(DFN[v]==0)        {            tarjan(v);            if(low[u]>low[v])                low[u]=low[v];        }        else if(instack[v]&&low[u]>DFN[v])            low[u]=DFN[v];    }    if(DFN[u]==low[u])    {        cornum++;        int v;        do        {            v=q.top();            color[v]=cornum;            instack[v]=0;            num[cornum]++;            q.pop();        }        while(v!=u);    }}void add(int u,int v){    G[u].push_back(v);}void init(){    tm=0;    for(int i=1;i<maxn;i++) G[i].clear();    memset(DFN,0,sizeof DFN);    memset(low,0,sizeof low);    memset(color,0,sizeof color);    memset(num,0,sizeof num);    memset(instack,0,sizeof instack);    cornum=0;}int main(){    while(~scanf("%d %d",&n,&m))    {        init();        int ww[maxn],vv[maxn];        for(int i=1;i<=m;i++)        {            scanf("%d %d",&ww[i],&vv[i]);            add(ww[i],vv[i]);        }        for(int i=1;i<=n;i++)        {            if(DFN[i]==0)                tarjan(i);        }        int du[maxn];        memset(du,0,sizeof du);        for(int i=1;i<=m;i++)        {            if(color[ww[i]]!=color[vv[i]])            {                du[color[ww[i]]]++;            }        }        int flag=0;        int k=0;        for(int i=1;i<=cornum;i++)        {            if(du[i]==0)            {                flag++;                k=i;            }        }        if(flag==1)        {            printf("%d\n",num[k]);        }        else            printf("0\n");                    }    return 0;}


原创粉丝点击