分析:题意是判断是不是连通无环的图,使用并查集可以很好的解决。
1、判断是否成环,只需判断输入边的两个点。有共同的祖先,那么这两点就成环。
2、判断是否连通,只要判断根节点数为1即可。
3、注意:当输入数据只有0 0时,也是满足条件的,应输出 "Yes"。
#include<iostream>
#include<algorithm>
using namespace std;
int p[100001];
bool Init(int n) //一开始指向自己
{
for(int i=0;i<=n;i++)
p[i]=i;
return true;
}
int Find(int x) //找到根节点
{
int r,i,j;
r=x;
while(r!=p[r]) r=p[r]; //路径压缩准备,找到根节点
i=x;
while(i!=p[i])
{
j=p[i];
p[i]=r;
i=j;
}
return i; //返回根节点
}
bool Merge(int x,int y) //返回是否需要合并
{
int tx,ty;
tx=Find(x);
ty=Find(y);
if(tx==ty) return false;
p[tx]=ty;
return true;
}
int main()
{
bool v[100001],flag;
int a,b,i,k;
while(cin>>a>>b)
{
if(a==-1 && b==-1)break;
if(a==0 && b==0) //只有0 0也输出Yes
{
cout<<"Yes"<<endl;
continue;
}
Init(100000);
memset(v,0,sizeof(v));
flag=0;
if(!Merge(a,b)) flag=1; //不需要合并则成环
v[a]=v[b]=1;
while(cin>>a>>b)
{
if(a==0 && b==0) break;
if(!Merge(a,b)) flag=1; //不需要合并则成环
v[a]=v[b]=1;
}
k=0;
for(i=1;i<=100000;i++)
if(v[i] && p[i]==i) //找根节点
k++;
if(k!=1 || flag) cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
return 0;
}
原文地址:http://blog.csdn.net/a809146548/article/details/44277157