HDU ACM 1325 / POJ 1308 Is It A Tree?

时间:2024-08-11 13:07:20

Is It A Tree?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6961    Accepted Submission(s): 1619

【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=1325

这题如果用并查集做的话,最后判断的时候还是要看一个结点的入度是否为大于1(纯并查集的情况下),搜了几份代码,有些是去判断是否有环的,这些都不如直接用树的充分条件去判断:一个节点入度为0,其余节点入读为1,V个点只有V-1条边,题目坑你的地方大概有两点:没节点也是树,结束时两个数是负数而不是两个-1

 #include <cstdio>
#include <cstring>
#define SIZE 2013
using namespace std;
int father[SIZE];
bool exit[SIZE];
int find(int f)
{
return father[f] = f == father[f] ? f : find(father[f]);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
int n, m, T = , max = , nv = , ne = ;
bool flag = true;
memset(father, , sizeof(father));
memset(exit, false, sizeof(exit));
while(scanf("%d%d", &n, &m) != EOF)
{
if(n < && m < ) break;
else if(n+m == )
{
if(ne == && nv == )
{
printf("Case %d is a tree.\n", ++T);
continue;
}
if(ne == nv-)
{
int cnt = , zero = ;
for(int i = ; i <= max; ++i)
if(exit[i])
{
if(!father[i]) zero++;
else if(father[i] == ) cnt++;
}
if(cnt == ne && zero == )
printf("Case %d is a tree.\n", ++T);
else
printf("Case %d is not a tree.\n", ++T);
}
else printf("Case %d is not a tree.\n", ++T); flag = true;
memset(exit, false, sizeof(exit));
memset(father, , sizeof(father));
ne = nv = ;
max = ;
}
else
{
max = max > n ? (max > m ? max : m) : (n > m ? n : m);
if(!exit[n])
{
exit[n] = true;
nv++;
}
if(!exit[m])
{
exit[m] = true;
nv++;
}
ne++;
father[m]++;
}
}
return ;
}