POJ 2186 Popular Cows (korasaju 算法)

Posted riotian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2186 Popular Cows (korasaju 算法)相关的知识,希望对你有一定的参考价值。

Description

每头牛都想成为牛群中的红人。给定n头牛和m个有序对(a,b),(a,b)表示牛a认为牛b是红人。该关系有传递性,所以如果牛a认为牛b是红人,牛b认为牛c是红人,那么牛a认为牛c也是红人。求被其他所有牛认为是红人的牛的总数

Input

第一行两个整数n和m表示牛数和关系数,之后m行每行两个整数a和b表示牛a认为牛b是红人

Output

输出被其他所有牛认为是红人的牛的个数

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

Solution

题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性 比如说A觉得B是popular and B thinks C is popular, then A thinks C is popalur also;
现在问有多少头牛是会被其他牛都仰慕。

思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕 算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0(不满足要求) 刚学korasaju 算法,所以用它做

Code

//Kosaraju 算法
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int VM=10010;
const int EM=50010;

struct Edge{
    int to,nxt;
}edge1[EM],edge2[EM];

int head1[VM],head2[VM],n,cnt;
int scc_id[VM],vis[VM],order[VM],k,scc;
int indeg[VM],outdeg[VM];

void addedge(int cu,int cv){
    edge1[cnt].to=cv;
    edge1[cnt].nxt=head1[cu];
    head1[cu]=cnt;

    edge2[cnt].to=cu;
    edge2[cnt].nxt=head2[cv];
    head2[cv]=cnt++;
}

void DFS(int u){
    for(int i=head1[u];i!=-1;i=edge1[i].nxt){
        int v=edge1[i].to;
        if(!vis[v]){
            vis[v]=1;
            DFS(v);
        }
    }
    order[++k]=u;
}

void reDFS(int u){
    for(int i=head2[u];i!=-1;i=edge2[i].nxt){
        int v=edge2[i].to;
        if(!scc_id[v]){
            scc_id[v]=scc;
            reDFS(v);
        }
    }
}

void Korasaju(){
    int i,u;
    k=scc=0;
    memset(vis,0,sizeof(vis));
    memset(scc_id,0,sizeof(scc));
    memset(order,0,sizeof(order));
    for(u=1;u<=n;u++)
        if(!vis[u]){
            vis[u]=1;
            DFS(u);
        }
    for(i=n;i>0;i--){
        u=order[i];
        if(!scc_id[u]){
            scc_id[u]=++scc;
            reDFS(u);
        }
    }
}

void Count_deg(){
    memset(indeg,0,sizeof(indeg));
    memset(outdeg,0,sizeof(outdeg));
    for(int u=1;u<=n;u++)
        for(int i=head1[u];i!=-1;i=edge1[i].nxt){
            int v=edge1[i].to;
            if(scc_id[u]!=scc_id[v]){
                indeg[scc_id[v]]++;
                outdeg[scc_id[u]]++;
            }
        }
}

int main(){

    //freopen("input.txt","r",stdin);

    int m;
    while(~scanf("%d%d",&n,&m)){
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        cnt=0;
        int u,v;
        while(m--){
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        Korasaju();
        Count_deg();
        int count=0,loc;
        for(int i=1;i<=scc;i++)
            if(outdeg[i]==0){
                count++;
                loc=i;
            }
        if(count>1)
            printf("0
");
        else{
            count=0;
            for(u=1;u<=n;u++)
                if(scc_id[u]==loc)
                    count++;
            printf("%d
",count);
        }
    }
    return 0;
}




以上是关于POJ 2186 Popular Cows (korasaju 算法)的主要内容,如果未能解决你的问题,请参考以下文章

Popular Cows(POJ 2186)

Poj2186Popular Cows

POJ 2186 Popular Cows

Popular Cows POJ - 2186(强连通分量)

POJ 2186 Popular Cows(Targin缩点)

POJ2186 Popular Cows [tarjan 缩点]