题意:
题目给你一组单向边,当遇到输入0 0就证明这是一组边,当遇到-1 -1就要停止程序。让你判断这是不是一棵树
题解:
题目很简单,但是程序要考虑的很多
1、因为是一颗树,所以肯定不能出现环,这个可以用并查集来判断
2、边数量+1==节点数量
3、每一个点的入度不能大于1(例如边a->b,这个b点的入度就要加1)
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 #include<map> 7 #include<vector> 8 #include<math.h> 9 #define mem(a,x) memset(a,x,sizeof(a)) 10 using namespace std; 11 typedef long long ll; 12 const int maxn=120000+10; 13 const int mod=26; 14 const int INF=0x3f3f3f3f; 15 const int Times = 10; 16 const int N = 5500; 17 int v[maxn],vis[maxn],sum[maxn]; 18 int flag=0; 19 int finds(int x) 20 { 21 if(x!=v[x]) 22 { 23 int y=finds(v[x]); 24 return v[x]=y; 25 } 26 return x; 27 } 28 void join(int a,int b) 29 { 30 int fa=finds(a),fb=finds(b); 31 if(fa!=fb) 32 v[fa]=fb; 33 else 34 flag=1; 35 } 36 int main() 37 { 38 int a,b,p=1,edge; 39 while(scanf("%d%d",&a,&b)) 40 { 41 flag=0; 42 edge=0; 43 for(int i=1; i<maxn; i++) 44 { 45 v[i]=i; 46 } 47 memset(vis,0,sizeof(vis)); 48 memset(sum,0,sizeof(sum)); 49 if(a<0&&b<0) 50 break; 51 if(a==0&&b==0) 52 { 53 printf("Case %d is a tree. ",p); 54 p++; 55 continue; 56 } 57 vis[a]=vis[b]=1; 58 join(a,b); 59 sum[b]++; 60 edge++; 61 while(scanf("%d%d",&a,&b)) 62 { 63 if(a==0&&b==0) 64 break; 65 join(a,b); 66 vis[a]=vis[b]=1; 67 sum[b]++; 68 edge++; 69 } 70 if(flag==1) 71 { 72 printf("Case %d is not a tree. ",p++); 73 } 74 else 75 { 76 int flagg=0,node=0; 77 for(int i=1; i<maxn; i++) 78 { 79 if(vis[i]==1) 80 node++; 81 if(sum[i]>1) 82 flagg=1; 83 } 84 if(node==(edge+1)&&flagg==0) 85 { 86 printf("Case %d is a tree. ",p++); 87 } 88 else 89 { 90 printf("Case %d is not a tree. ",p++); 91 } 92 } 93 } 94 }