上次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
题意:求并查集的个数,以及并查集中不能出现回路。
思路:两个while输入,判断条件跳出,将新输进去的数并入最小生成树,判断如果出现回路或者并入的出现
两个父节点,就输出No,最后判断最小生成树的个数,超过一的输出No,其他情况输出Yes,需要注意的是输
入0,0的话应是Yes。
#include<stdio.h>
#include<string.h>
int mp[100010],n,m,book[100010],q;
void init()
{
for(int i=0; i<100010; i++)
{
mp[i]=i;
book[i]=0;
}
}
int getf(int v)
{
if(mp[v]==v)
return v;
else
{
mp[v]=getf(mp[v]);
return mp[v];
}
}
void merg(int v,int u)
{
int t1,t2;
t1=getf(v);
t2=getf(u);
if(t1!=t2)
mp[t2]=t1;
else q=1;
book[v]=1;
book[u]=1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==-1&&m==-1)
break;
if(n==0&&m==0)
{
printf("Yes\n");
continue;
}
init();
q=0;
merg(n,m);
while(~scanf("%d%d",&n,&m)&&(n+m))
{
merg(n,m);
}
if(q==1)
{
printf("No\n");
continue;
}
else
{
int sum=0;
for(int i=0; i<100010; i++)
{
if(book[i]&&mp[i]==i)
sum++;
}
if(sum==1)
printf("Yes\n");
else printf("No\n");
}
}
}