题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=129
题目分析:
我觉得我理解的没有错啊,而且我的方法在其他的方法中应该是最优的,所有的数据都是边输入边得到的,但是为什么都是WA,很郁闷啊。基本上的例子也测试了。算了,以后再回来看吧~希望路过的大神留下足迹啊~~~
1、有环
2、某个节点有多个父节点,满足这两个条件之1都不是树。当然空树我已经考虑了,空树的话,连通区域个数为0
#include<stdio.h>
#include<string.h>
const int N = 10001;
int set[N];//由于这里是有向图,所以set[i]存放的是节点i的父节点。
bool used[N];//表示某个节点出现在树中
int Find(int k)
{
int r = set[k];
while(r != set[r])
r = set[r];
return r;
}
int main()
{
int a,b,t,i;
int r1,flag,cnt;
flag = 0;//是否有环或者有多个父亲
cnt = 0;
t = 0;//连通区域的数目
memset(used, 0, sizeof(used));
for(i = 0; i <= 10000; ++i)
set[i] = i;
while(scanf("%d %d", &a, &b))
{
if(a < 0 && b < 0)
break;
if(!a && !b)
{
if(!flag && t <= 1)
printf("Case %d is a tree.\n", ++cnt);
else
printf("Case %d is not a tree.\n", ++cnt);
flag = 0;
t = 0;
memset(used, 0, sizeof(used));
for(i = 0; i <= 10000; ++i)
set[i] = i;
}
else if(!flag)
{
r1 = Find(a);
//b不是根节点,有多个父亲或者b是根节点,出现环
if((set[b] != b && set[b] != a) || (set[b] == b && r1 == b))
{
flag = 1;
continue;
}
t = !used[b] ? t + 1 : t;
t = !used[a] ? t + 1 : t;
used[a] = used[b] =true;
if(set[b] == b)//减少一个根节点
--t;
set[b] = a;
}
}
return 0;
}