HDu 1269(強連通成分Tarjan入門)
6683 ワード
迷宮の城
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10075 Accepted Submission(s): 4529
Problem Description
希ちゃんの方向感覚を訓練するために、Gardonは大きな城を建てました.中にはN部屋(N<=10000)とM通路(M<=10000)があり、各通路は一方向です.つまり、ある通路がA部屋とB部屋につながっているとすれば、この通路を通ってA部屋からB部屋に着くことができることを説明するだけですが、B部屋からA部屋に着くことは説明しません.Gardonは、任意のiとjに対して、少なくとも1つの経路が部屋iから部屋jまで、1つの経路が部屋jから部屋iまでつながっているかどうかを確認するプログラムを書く必要があります.
Input
入力には複数のデータのセットが含まれ、入力された最初の行にはNとMの2つの数があり、次のM行には1行あたり2つの数aとbがあり、1つのチャネルがA部屋からB部屋に来ることができることを示している.ファイルは最後に2つの0で終了します.
Output
入力された各グループのデータについて、いずれの部屋も互いに接続されている場合は「Yes」を出力し、そうでない場合は「No」を出力します.
Sample Input
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
Sample Output
Yes
No
Author
Gardon
Source
HDU 2006-4 Programming Contest
テンプレート~
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10075 Accepted Submission(s): 4529
Problem Description
希ちゃんの方向感覚を訓練するために、Gardonは大きな城を建てました.中にはN部屋(N<=10000)とM通路(M<=10000)があり、各通路は一方向です.つまり、ある通路がA部屋とB部屋につながっているとすれば、この通路を通ってA部屋からB部屋に着くことができることを説明するだけですが、B部屋からA部屋に着くことは説明しません.Gardonは、任意のiとjに対して、少なくとも1つの経路が部屋iから部屋jまで、1つの経路が部屋jから部屋iまでつながっているかどうかを確認するプログラムを書く必要があります.
Input
入力には複数のデータのセットが含まれ、入力された最初の行にはNとMの2つの数があり、次のM行には1行あたり2つの数aとbがあり、1つのチャネルがA部屋からB部屋に来ることができることを示している.ファイルは最後に2つの0で終了します.
Output
入力された各グループのデータについて、いずれの部屋も互いに接続されている場合は「Yes」を出力し、そうでない場合は「No」を出力します.
Sample Input
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
Sample Output
Yes
No
Author
Gardon
Source
HDU 2006-4 Programming Contest
テンプレート~
1 #include <iostream>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <cstring>
5 #include <algorithm>
6 #define ll long long
7 using namespace std;
8 const int MAXN = 12000;
9 const int MAXM = 120000;
10 struct Edge
11 {
12 int to,next;
13 }edge[MAXM];
14 int head[MAXN],tot;
15 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
16 int Index,top;
17 int scc;
18 bool Instack[MAXN];
19 int num[MAXN];
20
21 void addedge(int u,int v)
22 {
23 edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
24 }
25 void Tarjan(int u)
26 {
27 int v;
28 Low[u] = DFN[u] = ++Index;
29 Stack[top++] = u;
30 Instack[u] = true;
31 for(int i = head[u]; i != -1; i = edge[i].next)
32 {
33 v = edge[i].to;
34 if( !DFN[v] )
35 {
36 Tarjan(v);
37 if(Low[u] > Low[v]) Low[u] = Low[v];
38 }
39 else if(Instack[v] && Low[u] > DFN[v])
40 Low[u] = DFN[v];
41 }
42 if(Low[u] == DFN[u])
43 {
44 scc++;
45 do
46 {
47 v = Stack[--top];
48 Instack[v] = false;
49 Belong[v] = scc;
50 num[scc]++;
51 }
52 while(v != u);
53 }
54 }
55 void solve(int N)
56 {
57 memset(DFN,0,sizeof(DFN));
58 memset(Instack,false,sizeof(Instack));
59 memset(num,0,sizeof(num));
60 Index = scc = top = 0;
61 for(int i = 1; i <= N; i++)
62 if( !DFN[i])
63 Tarjan(i);
64 }
65 void init()
66 {
67 tot = 0;
68 memset(head,-1,sizeof(head));
69 }
70 int main(void)
71 {
72 int n,m,a,b;
73 while(scanf("%d %d",&n,&m) ,n != 0 || m != 0)
74 {
75 init();
76 for(int i = 0; i < m; i++)
77 {
78 scanf("%d %d",&a,&b);
79 addedge(a,b);
80 }
81 solve(n);
82 if(scc == 1)
83 printf("Yes
");
84 else
85 printf("No
");
86 }
87 return 0;
88 }