POJ 2672 Tarjan + 缩点 + 拓扑思想
Going from u to v or from v to u?
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 17383 | Accepted: 4660 |
Description
In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?
Input
The first line contains a single integer T, the number of test cases. And followed T cases.
The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.
The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.
Output
The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.
Sample Input
1 3 3 1 2 2 3 3 1
Sample Output
Yes
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#
include
<cstdio>
#
include
<cstring>
#
include
<iostream>
#
include
<string>
#
include
<vector>
#
include
<stack>
#
include
<
set
>
#
include
<algorithm>
using
namespace
std;
#define N
1002
vector<
int
>Gra[N];
stack<
int
>Sta;
int
map[N][N];
int
dfn[N],low[N],inStack[N],belong[N],Time,cnt;
int
inDegree[N];
void
init()
{
Time = cnt =
0
;
memset(dfn,
0
,sizeof(dfn));
memset(low,
0
,sizeof(dfn));
memset(inStack,
0
,sizeof(inStack));
memset(inDegree,
0
,sizeof(inDegree));
memset(belong,
0
,sizeof(belong));
for
(
int
i=
0
;i<N;i++) Gra[i].clear();
memset(map,
0
,sizeof(map));
while
(!Sta.empty()) Sta.pop();
}
void
Tarjan(
int
s)
{
dfn[s] = low[s] = ++Time;
inStack[s] =
1
;
Sta.push(s);
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] ==
1
){
low[s] = min(low[s], dfn[j]);
}
}
if
(dfn[s] == low[s])
{
cnt ++;
while
(!Sta.empty()){
int
temp = Sta.top(); Sta.pop();
inStack[temp] =
0
;
belong[temp] = cnt;
if
(temp == s)
break
;
}
}
return
;
}
void
tsort()
{
for
(
int
k=
0
;k<cnt;k++){
int
fuck =
0
,pos;
for
(
int
i=
1
;i<=cnt;i++)
{
if
(inDegree[i] ==
0
)
{
fuck ++;
pos = i;
}
}
if
(fuck >
1
){
printf(
"No\n"
);
return
;
}
inDegree[pos ] = -
1
;
for
(
int
i=
1
;i<=cnt;i++)
{
if
(map[pos][i] ==
1
)
inDegree[i]--;
}
}
printf(
"Yes\n"
);
}
int
main()
{
int
noc;
cin>>noc;
while
(noc--)
{
init();
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);
}
for
(
int
i=
1
;i<=n;i++)
if
(dfn[i] ==
0
) Tarjan(i);
if
(cnt ==
1
) {
printf(
"Yes\n"
);
continue
;
}
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]){
if
(map[belong[i]][belong[k]] ==
0
){
map[belong[i]][belong[k]] =
1
;
inDegree[belong[k]]++;
}
}
}
}
for
(
int
i=
1
;i<=cnt;i++) printf(
"%d %d\n"
,i,inDegree[i]);
tsort();
}
}
|