//11159531 c00h00g 1308 Accepted 396K 0MS G++ 2471B 2013-01-05 16:30:10
//剧搓无比的代码
//情况太多了,一开始只考虑了,节点入度大于1和是否有一个共同祖先两个因素
//看了discuss,知道了还有几种情况没考虑,第一种是:1 2 2 1 0 0,这种会形成环,会导致我的findset一直递归(Memory Limit Exceeded)
//第二种情况是,1 1 0 0,节点指向自身,也是错误的
//还有一点比较郁闷的是,我将from,to放在全局会导致很奇怪的现象,读入的值在执行for(1001)语句后值突然改变,不知道什么原因
#include<cstdio>
#include<cstdio>
#include<string.h>
int parent[1001];
int indegree[1001];
int visited[1001];
//有可能会产生反复递归,1-2和2->1
int findset(int i){return parent[i]!=i?parent[i]=findset(parent[i]):i;}
int main(){
int cases=0;
int from,to,a,b;
while(scanf("%d%d",&from,&to)!=EOF){
cases++;
//0 0也算树,无语
if(from==0&&to==0){
printf("Case %d is a tree.\n",cases);
continue;
}
if(from==-1&&to==-1)
break;
if(from==to){
while(scanf("%d%d",&a,&b)){
if(a==0&&b==0)
break;
}
printf("Case %d is not a tree.\n",cases);
continue;
}
visited[from]=visited[to]=1;
int Max=-1;
if(Max<from) Max=from;
if(Max<to) Max=to;
int i;
for(i=0;i<=1001;i++){
visited[i]=0;
indegree[i]=0;
parent[i]=i;
}
parent[to]=from;
indegree[to]++;
bool flag=false;
while(scanf("%d%d",&a,&b)){
if(a==0&&b==0)
break;
//查看是否有环,查看a的父亲节点中是否有b
int tmp=a;
while(parent[tmp]!=tmp){
if(parent[tmp]==b){
flag=true;
break;
}
tmp=parent[tmp];
}
indegree[b]++;
if(indegree[b]>1){
flag=true;
//break;
}
if(Max<a) Max=a;
if(Max<b) Max=b;
parent[b]=a;
visited[a]=visited[b]=1;
}
if(flag){
printf("Case %d is not a tree.\n",cases);
}else{
int root,time=0;
bool flag1=false;
for(int i=0;i<=Max;i++){
if(visited[i]){
time++;
if(time==1)
root=findset(i);
else{
if(root!=findset(i)){
flag1=true;
break;
}
}
}
}
if(flag1){
printf("Case %d is not a tree.\n",cases);
}else{
printf("Case %d is a tree.\n",cases);
}
}
}
return 0;
}
POJ 1308
最新推荐文章于 2019-04-07 21:23:00 发布