不裸缩点》。。。POJ2186受欢迎的牛

不裸缩点》。。。POJ2186受欢迎的牛

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4930  Solved: 2626
[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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define N 10002
vector<int>Gra[N];
stack<int>Sta;
int low[N],dfn[N],inStack[N],belong[N],sum[N],outDegree[N],Time,cnt;
 
void Tarjan(int s)
{
    dfn[s] = low[s] = ++Time;
    Sta.push(s); inStack[s] = 1;
    for(int i=0;i<Gra[s].size();i++)
    {
        int j = Gra[s][i];
        if(dfn[j] == 0){
            Tarjan(j);
            low[s] = min(low[s], low[j]);
        }
        else if(inStack[j]){
            low[s] = min(low[s], dfn[j]);
        }
    }
    if(dfn[s] == low[s])
    {
        cnt++;
        while(!Sta.empty()){
            int k = Sta.top(); Sta.pop();
            sum[cnt] ++;
            belong[k] = cnt;
            inStack[s] = 0;
            if(k == s) break;
        }
    }
    return ;
}
 
int main()
{
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        Gra[x].push_back(y);
    }
    Time = cnt = 0;
    memset(sum,0,sizeof(sum));
    memset(inStack,0,sizeof(inStack));
    memset(outDegree,0,sizeof(outDegree));
    for(int i=1;i<=n;i++) if(dfn[i] == 0) Tarjan(i);
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<Gra[i].size();j++){
            int k = Gra[i][j];
            if(belong[i] != belong[k]){
                outDegree[belong[i]]++;
            }
        }
    }
    int outDegree_0 = 0;
    int ret ;
    for(int i=1;i<=cnt;i++)
    {
        if(outDegree[i] == 0){
            outDegree_0 ++;
            ret = sum[i];
        }
    }
    if(outDegree_0 > 1) printf("0");
    else printf("%d",ret);
}


 
posted @ 2017-07-30 15:27  swallowblank  阅读(209)  评论(0编辑  收藏  举报