题意:判断是否为树。
思路:
确实是道简单题。我也知道,只是有时候就是没耐性。
现在想通了,I can make it,never say never.
一味否定自己真是不应该!
嗯,主要就是判断三个方面嘛:
1、判断点的个数是否是边的条数加1.
2、判断是否有点的入度为2。我采用的是用vis数组标记判断。
3、判断是否有一个点即根节点的度数为0。(这个是我比赛的时候写漏的)
总结:
1、比赛的时候写漏第三个判断根,过不了 1 2 2 1 0 0这组数据。
2、由于有一个一组一组读入的判断结束 和 整个输入的判断结束,所以flag不能再while循环进入后初始化为
1。而是第一组前初始化为1,然后每一组完了输出结果后再初始化为1。
3、然后这种数据范围不明确的题,数组还是开大点。
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
int fa[100005];
int cnt[100005];
bool vis[100005];
int find(int r)
{
if(fa[r]==r) return r;
int t = find(fa[r]);
return t;
}
int main()
{
int cas=1,x,y,flag=1,c=0;
for(int i=1;i<=100000;i++)
{
fa[i]=i;
}
memset(vis,0,sizeof(vis));
while(scanf("%d%d",&x,&y)!=EOF)
{
if(x<0 && y<0)
break;
if(x==0 && y==0)
{
int sum=0,d=0;
for(int i=1;i<=100000;i++)
{
if(cnt[i])
{
sum++;
if(vis[i])
d++;
}
}
if(sum-1!=c || d==sum)
flag=0;
if(flag)
printf("Case %d is a tree.\n",cas++);
else printf("Case %d is not a tree.\n",cas++);
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
for(int i=1;i<=100000;i++)
fa[i]=i;
c=0;
flag =1;
continue;
}
if(!cnt[y]) cnt[y]++;
if(!cnt[x]) cnt[x]++;
if(!vis[y])
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
fa[fy]=fx;
c++;
}
vis[y]=true;
}
else
flag=0;
}
return 0;
}