poj 2186 Popular Cows 强连通分量 模板

版权声明:本博客内容基本为原创,如有问题欢迎联系,未经允许请勿转载 https://blog.csdn.net/qq_41955236/article/details/82110865

Popular Cows

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 40223   Accepted: 16381

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条关系。每条关系里有两个数x  y表示牛x崇拜牛y。现在问你,有多少牛会被其他所有的牛崇拜。

做法:

     先用强连通分量进行缩点,缩点后的一个分量代表这一块中的奶牛之间都是互相崇拜,再判断这个分量和其他分量之间的关系。如果存在有且只有一个强连通分量的出度为0,则这个强连通分量里的奶牛都被其他奶牛崇拜。我们来验证一下,如果存在有且只有一个强连通分量的出度为0,表示这一块里的奶牛没有崇拜别人,其他分量中的奶牛一定会有崇拜这个分量中的奶牛,为什么呢?假设,当前联通块3没有入度也没有出度,联通块1崇拜联通块2,而因为只有块3的出度为0,并且要保证块3没有入度,所以块2必须有指向块1的一条边,这样的块1和块2是一个更大的强连通分量,而这个分量的出度为0,则假设不成立,所以原命题成立。因此只要判断是不是有且只有一个强连通分量的出度为0就好,有的话再看看这个强连通分量里有多少奶牛,输出即可。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<vector>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=10005;
int n,m,head[maxn],now;
int belong[maxn],qiang,dfn[maxn],low[maxn],cnt;
int numqiang[maxn],out[maxn];
stack<int> sa;
vector<int> ve[maxn];
struct node{
    int from,to,next;
}e[50005];
void add(int u,int v){
    e[now].from=u;e[now].to=v;
    e[now].next=head[u],head[u]=now++;
}
void tarjan(int x){
    dfn[x]=low[x]=++cnt;
    sa.push(x);
    for(int i=head[x];~i;i=e[i].next){
        int v=e[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if(!belong[v]) low[x]=min(low[x],low[v]);
    }
    if(dfn[x]==low[x]){
        qiang++;
        while(1){
            int u=sa.top();sa.pop();
            belong[u]=qiang;
            if(u==x) break;
        }
    }
}
int main(){
    int x,y;
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d",&x,&y);
        add(x,y);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;i++){
        int x=belong[i];
        numqiang[x]++;
    }

    for(int i=0;i<now;i++){
        int fx=belong[e[i].from],fy=belong[e[i].to];
        if(fx!=fy){
            out[fx]++;
        }
    }
    int ans=0,sum=0,aim;
    for(int i=1;i<=qiang;i++){
        if(!out[i]) {
            sum++;
            aim=i;
        }
    }
    if(sum==1){
        for(int i=1;i<=n;i++){
            if(belong[i]==aim) ans++;
        }
        cout<<ans<<endl;
    }
    else cout<<"0"<<endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/82110865
今日推荐