[BZOJ1051][HAOI2006]受欢迎的牛

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 5981  Solved: 3147 [Submit][Status][Discuss]

Description

  每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。

Input

      第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)

Output

      一个数,即有多少头牛被所有的牛认为是受欢迎的。

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

HINT

100%的数据N<=10000,M<=50000
 
直接缩点,如果出度为0的点只有一个,输出这个点的大小即可,否则没有
 
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 10000 + 10, maxm = 50000 + 10;
inline int readint(){
    int f = 1, n = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch <= '9' && ch >= '0'){
        n = (n << 1) + (n << 3) + ch - '0';
        ch = getchar();
    }
    return f * n;
}
struct Edge{
    int to, next;
    Edge(){}
    Edge(int _t, int _n): to(_t), next(_n){}
}e[maxm];
int fir[maxn] = {0}, cnt = 0;
inline void add(int u, int v){
    e[++cnt] = Edge(v, fir[u]); fir[u] = cnt;
}
int sta[maxn], top = 0;
int dfn[maxn], low[maxn], Index = 0;
bool ins[maxn] = {false};
int belong[maxn], siz[maxn] = {0}, bcnt = 0;
int outd[maxn] = {0}, ans;
void dfs(int u){
    dfn[u] = low[u] = ++Index;
    sta[++top] = u;
    ins[u] = true;
    for(int v, i = fir[u]; i; i = e[i].next){
        v = e[i].to;
        if(!dfn[v]){
            dfs(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){
        int now;
        bcnt++;
        do{
            now = sta[top--];
            ins[now] = false;
            belong[now] = bcnt;
            siz[bcnt]++;
        }
        while(now != u);
    }
}
int main(){
    int n, m;
    n = readint();
    m = readint();
    for(int u, v, i = 1; i <= m; i++){
        u = readint();
        v = readint();
        add(u, v);
    }
    for(int i = 1; i <= n; i++)
        if(!dfn[i]) dfs(i);
    for(int v, u = 1; u <= n; u++)
        for(int i = fir[u]; i; i = e[i].next){
            v = e[i].to;
            if(belong[u] == belong[v]) continue;
            outd[belong[u]]++;
        }
    bool flag = false;
    for(int i = 1; i <= bcnt; i++){
        if(!outd[i]){
            if(flag){
                puts("0");
                return 0;
            }
            ans = siz[i];
            flag = true;
        }
    }
    printf("%d\n", ans);
    return 0;
}

 

 
posted @ 2017-08-26 21:37  jzyy  阅读(131)  评论(0编辑  收藏  举报