您的位置:首页 > 运维架构

poj 2186 Popular Cows(强连通分量)

2015-09-17 20:49 183 查看
题目:http://poj.org/problem?id=2186

Popular Cows

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 27673Accepted: 11139
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

分析:

题目大意:如果A牛崇拜B牛,B牛崇拜C牛,则A牛也崇拜C牛。寻找有多少头牛它被所有的其他的牛崇拜。

关于强连通图:如果有向图G的任何两顶点都互相可达,则称图G是强连通图,如果有向图G存在两顶点u和v,使得u不能到达v或者v不能到达u,则称图G是非强连通图。

关于强连通分量的tarjan算法可以阅读博客:/article/2611812.html

在有向无环图中有这样的点很特殊:outdegree=0 和 indegree=0的点。尝试将强连通分量压缩,通过缩点把杂乱的有向图变成一幅有向无环图,出度为0的点个数设为k,如果k=1那么就表明整个图是连通的,结果就是压缩点的个数,k>1则表明图不是连通的,结果是0。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int M=5e4+10,N=1e4+10;
int head
,ed;
struct node{
    int to,next;
}edge[M];
int sta
,vis
,low
,dfn
,out
,top;
void init(){
    ed=0;
    memset(head,-1,sizeof(head));
    memset(edge,0,sizeof(edge));
    memset(out,0,sizeof(out));
    memset(sta,0,sizeof(sta));
}
void addedge(int a,int b){
    edge[ed].to=b;
    edge[ed].next=head[a];
    head[a]=ed++;
}
void tarbfs(int k,int cnt,int &num){
    vis[k]=1;
    low[k]=cnt;
    dfn[k]=cnt;
    sta[top++]=k;
    for(int i=head[k];i>-1;i=edge[i].next){
        if(vis[edge[i].to]==0) tarbfs(edge[i].to,++cnt,num);
        if(vis[edge[i].to]==1) low[k]=min(low[k],low[edge[i].to]);
    }
    if(dfn[k]==low[k]){
        ++num;
        while(top>0&&sta[top]!=k){
            top--;
            low[sta[top]]=num;
            vis[sta[top]]=2;
        }
    }
}
int tarjan(int n){
    int num=0,cnt=1;
    top=0;
    memset(vis,0,sizeof(vis));
    memset(low,0,sizeof(low));
    for(int i=1;i<=n;i++){
        if(vis[i]==0) tarbfs(i,cnt,num);
    }
    return num;
}

int main()
{
    //freopen("cin.txt","r",stdin);
    int n,m;
    while(cin>>n>>m){
        int a,b;
        init();
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            addedge(a,b);
        }
        int num=tarjan(n); 
        for(int i=1;i<=n;i++){
            for(int j=head[i];j>-1;j=edge[j].next){
                if(low[i]!=low[edge[j].to]) out[low[i]]++;
            }
        }
        int sum=0,x;
        for(int i=1;i<=num;i++){
            if(out[i]==0){  sum++; x=i;  }
        }
        if(sum==1){
            sum=0;
            for(int i=1;i<=n;i++){
                if(low[i]==x) sum++;
            }
            printf("%d\n",sum);
        }
        else puts("0");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: