本题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272
Problem Description:
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
Input:
输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
整个文件以两个-1结尾。
整个文件以两个-1结尾。
Output:
对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"Yes",否则输出"No"。
Sample Input:
6 8 5 3 5 2 6 4
5 6 0 0
8 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 0
3 8 6 8 6 4
5 3 5 6 5 2 0 0
-1 -1
Sample Output:
Yes
Yes
No
解题思路:运用并查集中往集合中添加元素时的要求来解这道题。判断成环的时候,只要判断输入边的两个点有一个共同的父节点,那么这两个点就成环。
注意:只输入 0 0 的时候也是符合情况的,所以应该输出 “Yes”。
代码仅供参考(并查集模板):
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 const int maxn = 100005; 5 const int INF = 99999999; 6 using namespace std; 7 int par [maxn];//父节点 8 int sz[maxn];///高度,大小 9 int bian, dian;///边和点 10 int flag = 0;//为解决特殊元素 0 0的情况 11 void init () { 12 for (int i = 1; i < maxn; ++i) { 13 par[i] = i; 14 sz[i] = 1; 15 } 16 } 17 int find(int x) { 18 if (par[x] == x) { 19 return x; 20 } else { 21 return find (par[x]); 22 } 23 } 24 void unite (int x, int y) { 25 int fx = find (x), fy = find (y); 26 if (fx == fy) return; ///一家人就不往集合里面加 27 if (sz[fx] > sz[fy]) { 28 par[fy] = fx; 29 sz[fx] += sz[fy]; 30 if (dian < sz[fx]) //记录加到集合中的点 31 dian = sz[fx]; 32 } else { 33 par[fx] = fy; 34 sz[fy] += sz[fx]; 35 if (dian < sz[fy])//记录加到集合中的点 36 dian = sz[fy]; 37 } 38 } 39 int main () { 40 while (1) { 41 bian = 0, dian = 0; 42 int a, b; 43 init (); 44 while (scanf ("%d%d", &a, &b) != EOF) { 45 if (a == -1 && b == -1) //输入-1 -1 结束程序 46 exit (0); 47 if (a == 0 && b == 0){ 48 if (flag == 0) {////0 0是第一次输入的时候dian++ 49 dian ++; 50 } 51 if (flag == 1)//点0 0不是第一次输入的时候就不管,然后flag归位 0,为迎接下一次 52 flag = 0; 53 break; 54 } 55 if (a != b){ 56 if (flag == 0)//当有不是0 0输入的时候就把flag赋值1,为最后输入0 0时候做铺垫 57 flag = 1; 58 bian ++; 59 unite(a, b); 60 } 61 } 62 if (dian - 1 == bian) 63 printf("Yes "); 64 else 65 printf("No "); 66 } 67 return 0; 68 }
另外一种表达形式(c++map):
1 #include <cstdio> 2 #include <iostream> 3 #include <map> 4 #include <cstring> 5 using namespace std; 6 int main() 7 { 8 int i,j,k,T; 9 int from, to; 10 map <int ,int > mymap; 11 int cnt = 0; 12 while(cin>>from>>to,~from||~to) 13 { 14 cnt = 0;//几组数据 15 while(1) 16 { 17 if(!(from||to)) 18 break; 19 cnt++; 20 if(mymap.count(from)==0) 21 mymap[from] = to; 22 if(mymap.count(to)==0) 23 mymap[to] = from; 24 cin>>from>>to; 25 } 26 if(mymap.size()==0) 27 { 28 puts("Yes"); 29 continue; 30 } 31 if(mymap.size()==(cnt+1)) 32 puts("Yes"); 33 else 34 puts("No"); 35 mymap.clear(); 36 } 37 return 0; 38 }
欢迎码友评论,一起成长。