不裸缩点》。。。POJ2186受欢迎的牛
1051: [HAOI2006]受欢迎的牛
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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
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); } |