/*
HDOJ 1272
并查集的基本运用。
符合要求的情况是:
1、图是一个无环的图
2、图是连通图
特别注意,如果一开始就输入 0 0 是符合要求的
*/
#include <iostream>
using namespace std;
int p[100001]; //p[x]是x的父亲
int rank[100001]; //rank[x]是x的秩
int Find(int x)
{
int root,y,w;
y=x;
while(p[y] != y)
{
y=p[y];
}
root=y;
y=x;
while(p[y] != y) //路径压缩
{
w=p[y];
p[y]=root;
y=w;
}
return root;
}
void Union(int u,int v)
{
if(rank[u] <= rank[v])
{
p[u]=v;
if(rank[u] == rank[v])
++rank[v];
}
else
p[v]=u;
}
//初始化并查集
void Init()
{
for(int i=1;i<100001;i++)
{
p[i]=i;
rank[i]=0;
}
}
//输出答案
void answer(int flag)
{
if(flag == 1)
cout<<"No"<<endl;
else
{
//判断是否所有点都在一个集合里面
int f=0,allzero=0;
for(int i=1;i<100001;i++)
{
if(rank[i])
{
if(p[i] == i)
f++;
}
else
allzero++;
}
if((f == 1) || (allzero == 100000))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
int main()
{
int a,b,u,v,flag;
Init();
flag=0;
while(cin>>a>>b)
{
if((a == -1) && (b == -1))
break;
else if((a == 0) && (b == 0))
{
answer(flag);
Init();
flag=0;
}
else
{
rank[a]++;
rank[b]++;
u=Find(a);
v=Find(b);
if(u != v)
{
Union(u,v);
}
else
flag=1; //图中出现环
}
}
return 0;
}
并查集——HDOJ 1272
最新推荐文章于 2018-08-10 10:05:22 发布