不裸缩点》。。。POJ2186受欢迎的牛
不裸缩点》。。。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);
}
|