/*
HDOJ 1325
并查集的基本运用,考察树的基本定义
不能有环,不能是森林,每个点的入度最大为1.
*/
#include <iostream>
using namespace std;
const int Max=1001;
int rank[Max]; //顶点的秩
int p[Max]; //顶点x的父节点
int In[Max]; //存储每个顶点的入度
int find(int x)
{
int y,root,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_set()
{
for(int i=1;i<Max;i++)
{
rank[i]=0;
p[i]=i;
}
}
int main()
{
int a,b,u,v,n,iCase,flag_1,flag_2,f,i;
iCase=1;
while(cin>>a>>b)
{
if((a < 0)&&(b < 0))
break;
else if((a == 0)&&(b == 0))
{
cout<<"Case "<<iCase<<" is a tree."<<endl;
iCase++;
continue;
}
else
{
Init_set();
memset(In,0,sizeof(In));
rank[a]=1;
rank[b]=1;
In[b]++;
u=find(a);
v=find(b);
Union(u,v);
flag_1=1; //是否有环的标志
flag_2=1; //入度是否满足要求的标志
while(cin>>a>>b)
{
if(a+b == 0)
break;
rank[a]++;
rank[b]++;
In[b]++;
u=find(a);
v=find(b);
Union(u,v);
if(u == v)
flag_1=0;
}
f=0;
for(i=1;i<Max;i++)
if(rank[i] && p[i]==i)
f++;
for(i=1;i<Max;i++)
if(rank[i] && In[i]>1)
{
flag_2=0;
break;
}
if((flag_1 == 1) && (f == 1) && (flag_2 == 1))
cout<<"Case "<<iCase<<" is a tree."<<endl;
else
cout<<"Case "<<iCase<<" is not a tree."<<endl;
iCase++;
}
}
return 0;
}
并查集——HDOJ 1325
最新推荐文章于 2020-04-11 00:42:45 发布
本文解析了HDOJ1325问题,并通过并查集算法判断给定图是否构成一棵树。重点介绍了并查集的基本运用、如何检查是否存在环以及验证每个节点的入度是否满足树的条件。
430

被折叠的 条评论
为什么被折叠?



