首页 > 代码库 > poj 1308
poj 1308
这是一道关于并查集的题目。题目描述就是:给你一系列一维点与点之间的关系,要求你判断它们是否能组成一个树。
树要满足的条件有两个:(1)每个树只有一个根节点;(2)树的每个子节点只对应一个父节点。
#include<stdio.h>
#include<string.h>
int pa[200],r[200],d[200];//pa数组是用来存储每个子节点所对应的父节点;r数组是用来存储子节点对应父节点的个数的;d数组是用来确定哪些点事树的节点
int mark;
void set()
{
int i;
for(i=1;i<=199;i++)
{
pa[i]=i;
r[i]=0;
}
}
int find(int x)
{
int t;
t=x;
while(t!=pa[t])
{
t=pa[t];
}
return t;
}
void link(int x,int y)//用来合并两个点的
{
int a,b;
a=find(x);
b=find(y);
if(a!=b)//如果两个点的父节点不同,但又有父子关系则需要合并。
{
pa[b]=a;
r[b]++;
}
else//若两个节点有共同的父节点,这就说明这两者中至少有一个已经和其他的节点有父子关系,即它们中至少有一个的点连接有父节点,若要求这两者间有父子关系则其中一个节点的父节点就不唯一,与条件(2)不符
mark=0;
}
int main()
{
int a,b,num=0,f=1,n;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(f)
{
memset(d,0,sizeof(d));
num++;
mark=1;
set();
f=0;
}
if(a<0||b<0)
break;
if(a==0||b==0)
{
int j,root=0;
for(j=1;j<=199;j++)//该循环是用来判断树中所有节点的都是和同一根节点相连,即这是用来判断根节点的唯一性(也就是用来判断条件(1)是否满足)。
{
if(d[j]&&!root)
{
root=find(j);
}
else if(d[j])
{
if(root!=find(j))
mark=0;
}
}
if(mark==0)
printf("Case %d is not a tree.\n",num);
else
printf("Case %d is a tree.\n",num);
f=1;
}
d[a]=1;
d[b]=1;
link(a,b);
}
return 0;
}
poj 1308