迷宫城堡--HDOJ 1269(Tarjan)

迷宫城堡

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5732    Accepted Submission(s): 2543


Problem Description
为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。
 
Input
输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个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
思路:tarjan算法,很好的一个想法和思路,只需要对全图进行一次DFS 就行。
AC代码:
 1 /*=====================================================================
 2 # Author: wangzhili
 3 # Mail  : wangstdio.h@gmail.com
 4 # QQ : 240130760
 5 # Filename: tarjan.c
 6 # Last modified: 2013-12-06 09:18
 7 =====================================================================*/
 8 
 9 #include<stdio.h>
10 #include<string.h>
11 typedef struct
12 {
13     int to;
14     int next;
15 }EdgeNode;
16 EdgeNode edge[100005];
17 int dfn[10005],low[10005];
18 int head[10005],vis[10005];
19 int stack[10005];
20 int top,ind,cnt,n,m;
21 int min(int x,int y)
22 {
23     return x < y ? x : y;
24 }
25 
26 void tarjan(int i)
27 {
28     int j,v;
29     dfn[i] = low[i] = ++ind;
30     stack[++top] = i;
31     vis[i] = 1;
32     for(j = head[i]; j != -1;j = edge[j].next)
33     {
34         v = edge[j].to;
35         if(!dfn[v])
36         {
37             tarjan(v);
38             low[i] = min(low[i],low[v]);
39         }
40         else if(vis[v])
41             low[i] = min(low[i],dfn[v]);
42     }
43     if(dfn[i] == low[i])
44     {
45         cnt ++;
46         do
47         {
48             j = stack[top--];
49             vis[j] = 0;
50         }while(j != i);
51     }
52 }
53 void solve()
54 {
55     int i;
56     cnt = 0;
57     top = ind = 0;
58     memset(dfn,0,sizeof(dfn));
59     memset(vis,0,sizeof(vis));
60     for(i = 1;i <= n;i ++)
61     {
62         if(!dfn[i])
63             tarjan(i);
64     }
65     return ;
66 }
67 
68 int main()
69 {
70     int i,j;
71     int a,b;
72     freopen("in.c","r",stdin);
73     while(~scanf("%d%d",&n,&m) && (m+n))
74     {
75         memset(head,-1,sizeof(head));
76         for(i = 0;i < m;i ++)
77         {
78             scanf("%d%d",&a,&b);
79             edge[i].to = b;
80             edge[i].next = head[a];
81             head[a] = i;
82         }
83         solve();
84         if(cnt == 1)
85             printf("Yes
");
86         else
87             printf("No
");
88     }
89     return 0;
90 }
原文地址:https://www.cnblogs.com/anhuizhiye/p/3460809.html