【题目链接】
http://poj.org/problem?id=1308
题目意思
给n条有向路径,问是否能形成树。树的条件:1.每个点只有一个点指向它;2.不形成环;3。只有一个根节点。
解题思路
和HDU 1272 基本一样,需要注意的是空树叶是一棵树。除此之外也可以用树的性质解。直接判断不需要并查集。
代码部分
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
using namespace std;
#define LL long long
#define inf 0x3f3f3f3
const int N = 1e5+5;
bool fa;
int n,m,ans; ///ans根节点个数
int pre[N];
vector <int> num;
void init()
{
fa = true;
ans = 0;
num.clear();
for (int i = 0; i < N; i++)
pre[i] = i;
}
int fin(int x)
{
if (x != pre[x])
pre[x] = fin(pre[x]);
return pre[x];
}
void join (int x,int y)
{
int fx = fin(x);
int fy = fin(y);
if (y != pre[y]) ///已经有路径指向y
{
fa = false;
}
if (fx == fy) ///形成环
{
fa = false;
}
pre[fy] = fx;
}
int main()
{
init();
int cas=1;
while (~scanf("%d %d",&n,&m))
{
if (n == -1 && m == -1)
break;
if (n == 0 && m == 0)
{
if (fa)
{
if (num.size() == 0) ///空树
ans = 1;
for (int i = 0; i < num.size(); i++) ///判断是否是森林
{
if (pre[num[i]] == num[i])
{
pre[num[i]]= -1;
ans++;
}
}
if (ans == 1)
printf("Case %d is a tree.\n",cas++);
else printf("Case %d is not a tree.\n",cas++);
}
else printf("Case %d is not a tree.\n",cas++);
init();
}
else
{
//num.push_back(m);
num.push_back(n); ///只加入父节点就可以了
join(n,m);
}
}
return 0;
}