跟小希的迷宫基本一样,只是此题是有向图,要注意:1无环 2 只有一个入度为0的结点(根结点),不存在入度大于1的结点。输入结束条件是两个负数,而不是-1,不然会TLE。1 1 0 0 经证明,无此数据,不论是true或false,都可AC。
AC代码:
#include<stdio.h>
#define NUM 100005
int set[NUM];
int visit[NUM];
int lu[NUM];
void init()
{
int i;
for(i=0;i<=NUM;i++){
set[i]=i;
visit[i]=0;
lu[i]=0;
}
}
int find(int x)
{
int r=x;
while(set[r]!=r)
r=set[r];
return r;
}
void merge(int a, int b)
{
int x=find(a);
int y=find(b);
set[x]=y;
}
int main()
{
int a,b,i,flag,vex,count;
freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
init();
flag=1;
count=0;
vex=0;
while(scanf(" %d%d",&a,&b)!=EOF&&a>=0&&b>=0){
if(visit[a]==0){
vex++;
visit[a]=1;
}
if(visit[b]==0){
vex++;
visit[b]=1;
}
lu[b]++;
if(find(a)==find(b)&&a!=0&&b!=0&&a!=b){//如果是相同的根,会形成环
flag=0;
} else {
merge(a,b);
}
if(a==0&&b==0){
count++;
int cnt=0;
for(i=1;i<NUM;i++){//判断是否有2个以上的根
if(visit[i]==1&&set[i]==i)
cnt++;
if(cnt>1)
flag=0;
if(lu[i]>1)//不能有入度大于1的点
flag=0;
}
// if(vex==1)//1 1 0 0时为false,后来又实验为tree时也可以过
// flag=0;
if(flag==0)
printf("Case %d is not a tree.\n",count);
else printf("Case %d is a tree.\n",count);
init();
flag=1;
vex=0;
}
}
return 0;
}