题意:满足任意两个房间有且仅有一条路径可以相通(除非走了回头路)。
思路:判断整个图是否只有一个并查集,同时也要满足路数等于房间数减一。
注意:只输入0 0的情况输出“Yes”。
代码:
#include<stdio.h>
#include<string.h>
int a[100001],f[100001],lu[1000001],b[1000001];
struct yun
{
int u,v;
}p[1000001];
int getf(int u)
{
if(f[u]!=u)
f[u]=getf(f[u]);
return f[u];
}
void merge(int u,int v)
{
int t1=getf(u),t2=getf(v);
if(t1!=t2)
f[t2]=t1;
return ;
}
int main()
{
int a1,a2,i,j,s,c,d,sum,u;
while(~scanf("%d%d",&a1,&a2)&&a1!=-1&&a2!=-1)
{
if(a1==0&&a2==0)//只输入“0 0”时输出“Yes”。
{
printf("Yes\n");
continue;
}
memset(lu,0,sizeof(lu));
a[1]=a1;a[2]=a2;//将输入的第一组数据赋值给数组a.
lu[a1]=1;lu[a2]=1;//将输入的第一组数据标记。
p[1].u=a1;p[1].v=a2;//将输入的第一组数据赋值给结构体数组p。
j=2;s=2;
for(j=2,s=2,u=3;;j++)
{
scanf("%d%d",&c,&d);
if(c==0&&d==0)break;
p[j].u=c;p[j].v=d;//将输入的数据赋值给结构体数组p。
if(!lu[c])//将输入的数据标记,记录房间个数,再将数据赋值给数组a.
{
lu[c]=1;
s++;
a[s]=c;
}
if(!lu[d])//将输入的数据标记,记录房间个数,再将数据赋值给数组a.
{
lu[d]=1;
s++;
a[s]=d;
}
}
int t=j,e=s;//t-1为边数,e为房间数。
for(i=1;i<=e;i++)//将f数组赋初值。
f[a[i]]=a[i];
for(j=1;j<t;j++)//并查集
merge(p[j].u,p[j].v);
sum=0;
for(i=1;i<=e;i++)
if(f[a[i]]==a[i])//判断有几个并查集。
sum++;
if(sum!=1)printf("No\n");
else
{
if(s==t)
printf("Yes\n");
else printf("No\n");
}
}
}