在网上借鉴然后才写出来这个, 这个用到了压缩路径然后比之前的并查集多用到了一个flag来记录一些状态
添加visit数组来储存输入了多少数字,然后输入两个点时就对这两个点根节点查询,如果是就会形成环,输出no
在最后的判断然后要所有
#include<stdio.h>
#include<string.h>
int set[100001];
int visit[100001];
int flag;
int find_set(int i)
{
int k,t;
t=i;
while(t!=set[t])
t=set[t];
while(i!=t) //修改路径---压缩
{
k=set[i];
set[i]=t;
i=k;
}
return i;
}
void merge(int i,int j)
{
i=find_set(i);
j=find_set(j);
if(j==i)
flag=1;
else
set[i]=j;
}
int main()
{
int a,b,i,min,max;
while(scanf("%d%d",&a,&b)&&(a!=-1||b!=-1))
{
memset(visit,0,sizeof(visit));
visit[a]=visit[b]=1;
flag=0;
min=a<b?a:b;
max=a>b?a:b;
if(a==0&&b==0) //测试数据为 0 0 时候注意要输出 Yes
{
printf("Yes\n");
continue;
}
else if(a==b)
flag=1;
for(i=1;i<=100000;++i)
set[i]=i;
set[a]=b;
while(scanf("%d%d",&a,&b)&&(a!=0||b!=0))
{
visit[a]=visit[b]=1;
if(flag)
continue;
if(min>(a<b?a:b))
min=a<b?a:b;
if(max<(a>b?a:b))
max=a>b?a:b;
merge(a,b);
}
if(flag)
printf("No\n");
else //说明不存在回路
{
for(i=min;i<=max;++i) //判断是否连通
{
if(visit[i]==0) //没有出现的标号
continue;
if(set[i]==i)
++flag;
}
if(flag==1)
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}
的根节点都是一样的,才会都属于同一个集满足条件输出yes