题目大意:
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
解题思路:
当插入边的时候看这边的顶点是否存在相同的根,最后判断是否存在森林(即是否存在多个根),思路明了之后就可以用并查集来做了。
#include<stdio.h>
#include<queue>
#define N 100009
using namespace std;
int fa[N];
queue<int>q;
void initi()
{
int i;
for(i=0;i<=N;i++)
fa[i]=i;
while(!q.empty())
q.pop();
}
int getFa(int x)
{
int i,j;
i=j=x;
while(i!=fa[i])i=fa[i];
while(x!=fa[x]){
j=x;
x=fa[x];
fa[j]=i;
}
return i;
}
void add(int a,int b)
{
int x,y;
x=getFa(a);
y=getFa(b);
if(x!=y){
fa[x]=y;
}
}
int main()
{
int x,y,a,b,i,root;
bool flag;
while(scanf("%d%d",&x,&y)&&(x+y+2))
{
if(!x&&!y){
puts("Yes");
continue;
}
flag=true;
initi();
if(getFa(x)==getFa(y))
flag=false;
else{
add(x,y);
q.push(x);
}
while(scanf("%d%d",&a,&b)&&(a+b))
{
if(flag){
if(getFa(a)==getFa(b))
flag=false;
else{
add(a,b);
q.push(a);
}
}
}
i=q.front();q.pop();
root=getFa(i);
while(!q.empty()&&flag){
i=q.front();q.pop();
if(getFa(i)!=root){
flag=false;
}
}
if(flag)
puts("Yes");
else
puts("No");
}
}