分析:题意是判断是不是连通无环的图,使用并查集可以很好的解决。
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; }
时间: 2024-11-08 21:17:44