poj1308 题目链接
题目大意:输入若干组测试数据,输入 (-1 -1) 时输入结束。每组测试数据以输入(0 0)为结束标志。然后根据所给的所有(父亲, 孩子)数据对判断 是否能构成一棵树。
分析: 都以了解树只有一个根节点,那么我们就判断是不是有多个树;又知道每个节点只有一个父亲节点,那么我们就判断他是不是构成环, 成环则不是树。
注意: ①可以是空树; ②所给的节点构成森林(多个树)是不可以的,必须只能构成一棵树。
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int out, flag, x, y, num, pre[10010];
int find(int a)//查找根节点
{
int r, i, j;
r = a; i = a;
while(pre[r] != r)
r = pre[r];
while(pre[i] != r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
int main()
{
num = 0; out = 1;
while(out)
{
//先对所有节点的根节点进行初始化
for(int i = 1; i <= 10000; i++)
pre[i] = i;
flag = 1;
while(scanf("%d%d", &x, &y))
{
if(x == 0 && y == 0)
break;
else if(x == -1 && y == -1)
{
out = 0;
break;
}
int fx = find(x);
int fy = find(y);
//此处我们判断是否构成环
//如果x和y的根节点相同,那么他们已经是属于同一棵树
//若x又是y的父亲节点,那么将构成环
if(fx == fy)
flag = 0;
//如果x和y根节点不同,即不属于同一棵树, 那么将其合并成一棵树
else if(fx != fy)
pre[fy] = fx;
}
int k = 0;
//此处我们判断是不是森林,对所有节点(不包括没涉及的点)的根节点
//进行统计,若不都一样那么说明存在多个跟, 有多颗树, 否则是一棵树。
for(int i = 1; i <= 10000; i++)
{
int ans = find(i);
if(ans != i && k == 0)
k = ans;
else if(k != 0 && ans != i)
{
if(ans != k)
flag = 0;
}
}
if(out == 1 && flag == 0)
printf("Case %d is not a tree.\n", ++num);
else if(out == 1 && flag == 1)
printf("Case %d is a tree.\n", ++num);
}
return 0;
}
杭电的1272 和这个题差不多 稍微改改就可以了。
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int out, flag, x, y, pre[100010];
int find(int a)
{
int r, i, j;
r = a; i = a;
while(pre[r] != r)
r = pre[r];
while(pre[i] != r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
int main()
{
out = 1;
while(out)
{
for(int i = 1; i <= 100000; i++)
{
pre[i] = i;
}
flag = 1;
while(scanf("%d%d", &x, &y))
{
if(x == 0 && y == 0)
break;
else if(x == -1 && y == -1)
{
out = 0;
break;
}
int fx = find(x);
int fy = find(y);
if(fx != fy)
{
pre[fx] = fy;
}
else if(fx == fy)
{
flag = 0;
}
}
int k = 0;
for(int i = 1; i <= 100000; i++)
{
int ans = find(i);
if(ans != i && k == 0)
k = ans;
else if(k != 0 && ans != i)
{
if(ans != k)
flag = 0;
}
}
if(out == 1 && flag == 0)
printf("No\n");
else if(out == 1 && flag == 1)
printf("Yes\n");
}
return 0;
}

本文详细解读POJ1308题目,通过输入数据判断是否构成一棵树,涉及树的特性、环的判断及森林概念。算法采用并查集思想,通过查找根节点和合并操作实现树的构建与判断。
1781

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



