您的位置:首页 > 其它

POJ 1308 Is It A Tree?

2013-11-15 10:18 260 查看
首先,先明确题意:

以下情况不是树:

1.可以由不同路径到达一个结点的;

2.结点之间形成环的。eg 1 2 2 3 3 4 4 1 0 0

3.根结点不止一个的。

4.重复输入的。eg 1 2 1 2 0 0

5.0 0也是一棵树
好的,现在知道题意了,运用并查集的相关知识就可以解决了,详解见注释

#include <iostream>
#include<stdio.h>
#include<cstring>

using namespace std;
int father[50000];
int re[50000];
int i,tree;

int find(int a){
int fa=father[a];
if(a!=father[a]){
father[a]=find(father[fa]); //注意递归的使用,表示我不会写递归啊有木有
return father[fa];
}
else return fa;
}

void link(int a,int b){
int x=find(a);
int y=find(b);
re[i++]=x; //记录下每次的根节点
if(y!=b||y==x){tree=0;return;}//如果y!=b说明之前b有不等于自己的父亲节点,所以现在b不止有一个父亲节点 y==x说明形成环
else father[b]=x;
}

int main()
{ int count=1;
int temp_x,temp_y;
while(scanf("%d %d",&temp_x,&temp_y))
{
if(temp_x+temp_y<0) break;
for(int k=0;k<50005;k++)
father[k]=k; //父亲结点初始化为自己
i=0;
int fa=temp_x;
int son=temp_y;
int ok=1;
tree=1;
while(1)
{ if(ok==0){scanf("%d %d",&fa,&son);}
if(fa+son==0){break;}
link(fa,son);
ok=0;
}
int root=find(re[0]);
for(int j=1;j<i;j++)
if(find(re[j])!=root) //查询之前记录的每个根节点的最终根结点是否为同一个,因为根结点在之后输入的数据中可能会更新
{ tree=0;break;}

if(tree==0)printf("Case %d is not a tree.\n",count++);
else printf("Case %d is a tree.\n",count++);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: