# include<stdio.h>
int set[100001];//记录根节点
int find(int x)
{
if(set[x]!=x)
set[x]=find(set[x]);
return set[x];
}
void Combain(int pa,int pb)
{
if(pa>pb)
set[pa]=pb;
else
set[pb]=pa;
}
int main()
{
int i,a,b,pa,pb,flag,max,min;
bool use[100001];//标记走过的路
while(scanf("%d%d",&a,&b))
{
if(a==0&&b==0)
{
printf("Yes\n");
continue;
}
if(a==-1&&b==-1)
break;
for(i=1;i<=100001;i++)
{
set[i]=i;
use[i]=false;
}
max=0;min=100001;
flag=0;
for(i=1;a!=0&&b!=0;i++)
{
if(max<a)max=a;
if(max<b)max=b;
if(min>a)min=a;
if(min>b)min=b;
pa=find(a);
pb=find(b);
use[a]=use[b]=true;
if(pa==pb)
//非法走到一块,即通过两条不同的路走到了一块,那必定构成了一个连通图
flag++;
else
Combain(pa,pb);
scanf("%d%d",&a,&b);
}
for(i=min;i<=max;i++)
//是否存在多个集合
if(use[i]&&set[i]==i)
flag++;
if(flag==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
附另一方法:如果不连通,边数始终会比点少一!!
#
include<stdio.h>
int main()
{
int
a,b,count,i,min,max,flag;
bool
use[100001];
while(scanf("%d%d",&a,&b))
{
if(a==-1&&b==-1)
break;
if(a==0&&b==0)
{
printf("Yes\n");
continue;
}
count=0;
flag=0;
for(i=1;i<=100001;i++)
use[i]=false;
min=100001;max=0;
for(i=1;a!=0&&b!=0;i++)
{
if(min>a)min=a;
if(min>b)min=b;
if(max<a)max=a;
if(max<b)max=b;
use[a]=use[b]=true;
scanf("%d%d",&a,&b);
++count;
}
for(i=min;i<=max;i++)
if(use[i])
flag++;
if(flag-count==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}