HDU 1272 小希的迷宫(并查集)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1272 小希的迷宫(并查集)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1272
题目大意:上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
解题思路:常规并查集,注意几点:
①当a 和b有相同头节点,也就是a,b已经属于同一个并查集,再连接a b则会成环。
②当输入为0 0是即迷宫为空,答案为Yes.
③不能有多片森林,所有点只能在一个并查集中。
代码:
1 #include<stdio.h> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 using namespace std; 6 const int N=1e5+5; 7 int root[N]; 8 vector<int>v; 9 int find(int x){ 10 return root[x]==x?x:root[x]=find(root[x]); 11 } 12 13 int main(){ 14 int a,b; 15 while(~scanf("%d%d",&a,&b)){ 16 bool flag=true; 17 if(b==-1&&a==-1) 18 break; 19 //判断是否森林为空 20 if(a==0&&b==0) 21 puts("Yes"); 22 v.clear(); 23 for(int i=1;i<=N;i++){ 24 root[i]=i; 25 } 26 root[a]=b; 27 v.push_back(a); 28 v.push_back(b); 29 while(~scanf("%d%d",&a,&b)&&(a||b)){ 30 int t1=find(a); 31 int t2=find(b); 32 v.push_back(a); 33 v.push_back(b); 34 //判断是否会成环 35 if(t1==t2) 36 flag=false; 37 root[t1]=t2; 38 } 39 //判断所有点在同一个并查集内 40 int tmp=find(v[0]); 41 for(int i=1;i<v.size();i++){ 42 int t=find(v[i]); 43 if(t!=tmp) 44 flag=false; 45 } 46 if(flag) 47 puts("Yes"); 48 else 49 puts("No"); 50 } 51 return 0; 52 }
以上是关于HDU 1272 小希的迷宫(并查集)的主要内容,如果未能解决你的问题,请参考以下文章