题目:
给出一对对的数字a,b,表示从a到b有一条边。判断这是不是一棵树。
- 多case,每个case以0 0 结尾
- 输入以-1 -1结尾
分析:①每个节点(除了根结点)只有一个入度;②只有一个根结点。
森林:多个根。
入度:指向同一个结点的边数。
将点逐个加入集合中,然后判断就行了。
#include<stdio.h>
#include<algorithm>
using namespace std;
int flagt;//判断是否成树
int vis[10005];//标记用过的结点
int pre[10005];
int find(int x)//压缩路径 并查找
{
return pre[x]==x?x:pre[x]=find(pre[x]);
}
void Merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fy!=fx)
pre[fy]=fx;
}
void init()
{
int i;
for(i=1;i<=10005;i++)
{
pre[i]=i;
vis[i]=0;
}
}
int judge_tree(int n) //判断是否只有一个根结点。
{
int i=1;
while(i<=n && !vis[i])
i++;
int f1=find(i);
while(i<=n)
{
if(vis[i] && find(i)!=f1)
return 0;
i++;
}
return 1;
}
int main()
{
int i,j,k=1;
int x,y,range;
flagt=1;
range=0;
init();
while(scanf("%d%d",&x,&y)!=EOF)
{
if(x<0 || y<0)
return 0;
if(x==0 || y==0) //输入0 0时判断。
{
if(flagt && judge_tree(range))
printf("Case %d is a tree.\n",k++);
else
printf("Case %d is not a tree.\n",k++);
flagt=1;
range=0;
init();
continue;
}
if(!flagt)
continue;
range=max(range,max(x,y));//所涉及到的最数值最大的点。
vis[x]=vis[y]=1;
if(find(x)==find(y))//他们有共同的根结点,并且他们之间还有父子关系(即有边相连),则无法形成树。
flagt=0;
Merge(x,y);
}
return 0;
}