这题竟然卡了那么长时间。。。哈哈哈哈终于过了
大致思路:判断是否连通,是否成环,是否满足每个节点的入度 <= 1。
大致思路:判断是否连通,是否成环,是否满足每个节点的入度 <= 1。
注意两(坑)点:要特判开始为 0 的情况;都 小于 0的时候结束。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
int per[1000005];
bool vis[1000005];
int in[1000005]; //入度;
int find(int x)//找根节点;
{
int r = x;
while(r != per[r])
{
r = per[r];
}
int i = x,j;
while(i != r)
{
j = per[i];
per[i] = r;
i = j;
}
return r;
}
void join(int x,int y)//合并;
{
per[x] = y;
}
void init()//初始化;
{
for(int i = 0; i < 1000005; i ++)
{
per[i] = i;
vis[i] = false;
in[i] = 0;
}
}
int main()
{
int x,y,T=1;
while(scanf("%d%d",&x,&y)!= EOF)
{
if(x <0 && y <0)
break;
if(x == 0 && y == 0)//特判开始为0的情况;
{
printf("Case %d is a tree.\n",T);
T++;
continue;
}
init();
vis[x] = true;
vis[y] = true;
in[y] ++; //入度加一;
int flag = 0;
int maxn = 0;
maxn = max(maxn,x);
maxn = max(maxn,y);
while(x!= 0 && y!= 0)
{
int s = find(x);
int e = find(y);
if(s == e)//判断是否成环;
{
flag = 1;
}
else
join(s,e);
scanf("%d%d",&x,&y);
vis[x] = true;
vis[y] = true;
in[y] ++;
maxn = max(maxn,x);
maxn = max(maxn,y);
}
//printf("%d",flag);
if(flag == 1)
{
printf("Case %d is not a tree.\n",T);
T++;
continue;
}
int cnt = 0;
for(int i = 1; i <= maxn; i ++)
{
if(vis[i] && per[i] == i ) //判断是否连通;
cnt ++;
}
// printf("%d",cnt);
if(cnt != 1)
{
printf("Case %d is not a tree.\n",T);
T++;
continue;
}
int g = 0;
for(int i = 1; i <= maxn; i ++)
{
if(vis[i] && in[i]>1) //判断是否每个节点的入度 <= 0;
{
printf("Case %d is not a tree.\n",T);
T++;
g = 1;
break;
}
}
if(g == 1)
continue;
//若以上三个条件都满足,则符合题意;
printf("Case %d is a tree.\n",T);
T++;
}
return 0;
}
如有错误,欢迎指出~