上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
整个文件以两个-1结尾。
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
Yes Yes No
1》判断成环的时候,只要判断输入边的两个点。有一个共同的父节点,那么这两个点就成环。
2》判断连通的时候,只要判断根节点数为1即可。
注意:当输入的这组数据只有 0 0 时,依然是满足条件的,即应输出 "Yes"。
代码如下:
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define MAX 100001
bool mark[MAX];
int parent[MAX];
int findp(int a) //查找
{
while(a!=parent[a])
a=parent[a];
return a;
}
bool merge(int a,int b) //判断
{
int x=findp(a);
int y=findp(b);
if(x==y)
return 0;
parent[y]=x;
return 1;
}
int main()
{
int x,y;
while(~scanf("%d%d",&x,&y))
{
if(!x&&!y)
{
puts("Yes");
continue;
}
if(x==-1&&y==-1)
break;
int i;
for(i=1;i<MAX;i++)
parent[i]=i;
memset(mark,0,sizeof(mark));
mark[x]=mark[y]=1;
merge(x,y);
int n=1,flag=1;
while(~scanf("%d%d",&x,&y))
{
if(!x&&!y)
break;
if(!mark[x])
{
n++;
mark[x]=1;
}
if(!mark[y])
{
n++;
mark[y]=1;
}
if(merge(x,y))
n--;
else
flag=0;
}
if(flag&&n==1)
puts("Yes");
else
puts("No");
}
return 0;
}