闲的没事,做一道POJ,已经AC胡哥题册142个题了,好期待200题的大奖啊。扯远了。。
这个题太简单了,并查集的简单应用,输入有挺多坑的。
1 : 空树是一棵树。
2: :自己不能指向自己。
3 : 不能有重复边。
4 : 两个树合并的时候必须至少有一个点是祖先。
5 : 即使输入结束前已经判断完毕,也得输入结束。
//============================================================================
//
// > File : poj1308.cpp
// > Author : flowertree
// > Time : 2015年11月10日
// > Algorithm : 并查集 判断是否能组成一棵树
//
//============================================================================
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX 1005
int f[MAX];
bool v[MAX];
void Init()
{
for(int i = 0; i < MAX; i++)
f[i] = i;
}
int find(int x)
{
if(f[x] == x)
return x;
else
return f[x] = find(f[x]);
}
bool Union(int x, int y)
{
int fx, fy;
if(x == y)
return false;
fx = find(x);
fy = find(y);
if(fx == fy)
{
return false;
}
if(fx != x && fy != y)
{
return false;
}
else
{
f[fy] = fx;
return true;
}
}
int main()
{
int m, n;
int mark;
int Case = 1;
bool flag, signal;
while(cin >> m >> n)
{
if(m == -1 && n == -1)
break;
if(m == 0 && n == 0)
{
printf("Case %d is a tree.\n", Case++);
continue;
}
memset(v, false, sizeof(v));
v[m] = true;
v[n] = true;
Init();
flag = Union(m, n);
signal = true;
if(!flag)
{
signal = false;
}
while(cin >> m >> n)
{
if(!(m && n))
break;
if(!flag || !signal)
continue;
v[m] = true;
v[n] = true;
flag = Union(m, n);
}
if(!flag || !signal)
{
printf("Case %d is not a tree.\n", Case++);
continue;
}
//判断是否为森林
mark = 0;
for(int i = 0; i < MAX; i++)
{
if(f[i] == i && v[i] == true)
mark++;
}
if(mark == 1)
printf("Case %d is a tree.\n", Case++);
else
printf("Case %d is not a tree.\n", Case++);
}
system("pause");
return 0;
}