POJ2186-Popular Cows

来源:互联网 发布:淘宝阿里旺旺卖家版 编辑:程序博客网 时间:2024/06/05 14:20

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 35075 Accepted: 14295
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.
Source

USACO 2003 Fall

题目大意:有n头牛,有单向喜欢关系,具有传递性,问受所有牛喜欢的牛有多少个。
解题思路: Tarjan求强连通分量,缩点,判断出度为0的点是否只有一个,若是,则输出该强连通分量里点的个数。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>using namespace std;const int MAXN=2e5+5;const int MAXM=5e5+5;int head[MAXN],tot;int low[MAXN],dfn[MAXN],sta[MAXN],bel[MAXN];//bel数组的值是1~sccint index,top;int scc;//强连通分量的个数bool instack[MAXN];int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc//num数组不一定需要,结合实际情况int n,m;struct Edge{    int from,to,nxt;}edge[MAXM];void addedge(int u,int v){    edge[tot].from=u;    edge[tot].to=v;    edge[tot].nxt=head[u];    head[u]=tot++;}void tarjan(int u){    int v;    low[u]=dfn[u]=++index;    sta[top++]=u;    instack[u]=true;    for(int i=head[u];i!=-1;i=edge[i].nxt)    {        v=edge[i].to;        if(!dfn[v])        {            tarjan(v);            if(low[u]>low[v]) low[u]=low[v];        }else if(instack[v]&&low[u]>dfn[v])        low[u]=dfn[v];    }    if(low[u]==dfn[u])    {        scc++;        do        {            v=sta[--top];            instack[v]=false;            bel[v]=scc;            num[scc]++;        }while(v!=u);    }}void solve(int n){    memset(dfn,0,sizeof(dfn));    memset(instack,false,sizeof(instack));    memset(num,0,sizeof(num));    index=scc=top=0;    for(int i=1;i<=n;i++)    {        if(!dfn[i]) tarjan(i);    }}void init(){    tot=0;    memset(head,-1,sizeof(head));}int out[MAXN];void suodian(){    memset(out,0,sizeof(out));    //for(int i=1;i<=scc;i++) G[i].clear();    for(int i=0;i<m;i++)    {        int u=bel[edge[i].from];        int v=bel[edge[i].to];        if(u!=v)        out[u]++;    }    int cnt=0,p;    for(int i=1;i<=scc;i++)    {        if(out[i]==0)        {            cnt++;            p=i;        }    }    if(cnt!=1) printf("0\n");    else    {        printf("%d\n",num[p]);    }}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        init();        int u,v;        for(int i=1;i<=m;i++)        {            scanf("%d%d",&u,&v);            addedge(u,v);        }        solve(n);//        cout<<scc<<endl;//        for(int i=1;i<=n;i++)//        {//            cout<<bel[i]<<endl;//        }//        cout<<num[1]<<" "<<num[2]<<endl;        suodian();    }    return 0;}/*3 31 22 12 3*/
原创粉丝点击