HDU-1272-小希的迷宫
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1272
/*
程序分析:
题目意思其实就是让你判断一个图是不是一棵树,条件就是无环、连通图,即连通分支为一
解决方法:
利用并查集,把输入的房间视为一个点,有路径的就连成一起,只要找到了环,就可以判定为NO了,
如果到输入最后都还没找到环就只剩两种可能了,一种就是只有一棵书,一种就是有一个以上的树,这样也可以判定是否符合问题要求了。
*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 4 const int Max = 100000+10; 5 int Far[Max]; 6 int Rank[Max]; 7 int Sign[Max]; 8 9 void Make_set(int n) 10 { 11 int i; 12 for(i=0; i<=n; i++) 13 { 14 Far[i] = i; 15 } 16 memset(Rank, 0, sizeof(Rank)); 17 memset(Sign, 0, sizeof(Sign)); 18 } 19 20 int Find_set(int x) 21 { 22 if(Far[x] != x) 23 return Far[x] = Find_set(Far[x]); 24 return Far[x]; 25 } 26 27 void Unio(int a, int b) 28 { 29 a = Find_set(a); 30 b = Find_set(b); 31 if(a == b) 32 return; 33 if(Rank[a] < Rank[b]) 34 Far[a] = b; 35 else if(Rank[a] > Rank[b]) 36 Far[b] = a; 37 else 38 { 39 Far[a] = b; 40 Rank[b]++; 41 } 42 } 43 44 int main() 45 { 46 int a, b; 47 //初始化 48 int flag = 1; 49 Make_set(Max); 50 while(cin>>a>>b && a!=-1 && b!=-1) 51 { 52 if(a == 0 && b == 0) //待一组数据输入完毕后才输出结果 53 { 54 int ans = 0; 55 for(int i=1; i<=Max; i++) 56 { 57 if(Sign[i] && Find_set(i) == i) //统计有几个连通分支 58 ans++; 59 } 60 if(ans > 1) //连通分支大于1,表示还有有个别房间不能连通 61 flag = 0; 62 if(flag) 63 cout<<"Yes"<<endl; 64 else 65 cout<<"No"<<endl; 66 //从新初始化 67 flag = 1; //表示为Yes 68 Make_set(Max); 69 continue; 70 } 71 if(a != b && Find_set(a) == Find_set(b)) //根节点相同,但叶子不同,表示a,b已存在路径,如果 72 { //仍增加一条路径则会存在环,则有第二天路径 73 //cout<<"No"<<endl; 74 flag = 0; 75 } 76 else 77 { 78 Sign[a] = 1; 79 Sign[b] = 1; 80 Unio(a, b); 81 } 82 } 83 return 0; 84 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 bool used[100001]; 5 int r[100001]; 6 int find(int x) 7 { 8 while(r[x]!=x) 9 x=r[x]; 10 return x; 11 } 12 int uni(int x,int y) 13 { 14 x=find(x); 15 y=find(y); 16 if(x=y)return 0; 17 r[x]=y; 18 return 1; 19 } 20 int main() 21 { 22 int n,m,flag,i,t; 23 while(cin>>n>>m) 24 { 25 if(n==-1&&m==-1)return 0; 26 if(n==0&&m==0) 27 { 28 cout<<"Yes\n"; 29 continue; 30 } 31 memset(used,0,sizeof(used)); 32 for(i=0;i<100001;i++) 33 { 34 r[i]; 35 } 36 uni(n,m); 37 used[n]=used[m]=1;t=1; 38 flag=1; 39 while(cin>>n>>m) 40 { 41 if(n==0&&m==0)break; 42 if(used[n]==0){t++;used[n]=1;} 43 if(used[m]==0){t++;used[m]=1;} 44 if(uni(n,m)==0)flag=0; 45 else t--; 46 } 47 if(flag&&t==1)cout<<"Yes\n"; 48 else cout<<"No\n"; 49 } 50 return 0; 51 52 }