题目:
输入一系列数字对x y,表示x是y的父结点。判断这是不是一棵树。
输入0 0表示输出判断结果,-1 -1表示退出程序。

 思路:

北大 2012 Is It A Tree?

过程:

如果已经判断不是树,则接下来输入边后,直接continue,不要再处理。这样可提高运行速度。

这题坑得我不行不行的:
虽然示例有显示换行,然而,不需要换行!!!!!

1 1 0 0 不是树!不能自己指向自己!!!!!单独一个根结点,竟然默认不是树!!!!坑死当年做题的小朋友们啊~~~~~~
1 2 1 2 0 0 不是树......只是重复输入边而以,竟然直接默认不是树了!!!!!!!!!!!

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cstring>                  
 4 using namespace std;
 5 
 6 //并查集
 7 /*
 8 1.node[i]=i:本题默认不合法,直接不是树
 9 2.node[i]!=-1:参与,且为子结点
10 3.node[i]==-1:为根
11 4.node[i]==0:不存在该点
12 */
13 int node[10002];      //node[i]:结点i的父结点
14 //判断是否有环
15 bool ishaveCircle(int y){
16     int y1=y;
17     if(node[y]==0)          //不存在的点,不是环
18         return false;
19                             //找到根结点,或是绕回到自己,则退出循环
20     while(node[y1]!=-1 && node[y1]!=y)
21         y1=node[y1];
22     if(node[y1]==-1)        //找到根结点,不是环
23         return false;
24     else
25         return true;        //绕回到自己,是环
26 }
27 
28 int main(){
29     int x,y;                           //边:x->y
30     int caseI=1;                       //第几次测试
31     int edgeNum=0;                     //边的数量
32     int rootNum=0;                     //根的个数
33     bool isTree=true;                  //判断是不是树
34 
35     memset(node,0,10002*sizeof(int));  //清理干净,开始新的判断
36     while(scanf("%d %d",&x,&y)!=EOF){  //输入数字对
37         if(x==-1 && y==-1)                   //退出程序
38             return 0;
39         if(x==0 && y==0){                    //输出结果
40             if(!isTree)                            //不是树,输出结果
41                 printf("Case %d is not a tree.\n",caseI); 
42             else{                                  //需要进一步判断
43                 if(edgeNum==0){                          //0条边:空树
44                     printf("Case %d is a tree.\n",caseI); 
45                 }
46                 else{                                    //有边的情况:判断是树还是森林(即是有几个根)
47                     if(rootNum==1)                             //为一棵树
48                         printf("Case %d is a tree.\n",caseI); 
49                     else                                       //为一片森林:不是树
50                         printf("Case %d is not a tree.\n",caseI); 
51                 }
52             }
53 
54             memset(node,0,10002*sizeof(int));      //清理干净,开始新的判断
55             isTree=true;                           //恢复isTree变量
56             caseI++;                               //测试次数加1
57             edgeNum=0;                             //边的数量归0
58             rootNum=0;                             //根的个数归0            
59             continue;
60         }
61 
62         if(!isTree)                          //既然已判定不是树,则输入的边不用处理
63             continue;
64         if(node[y]==0 || node[y]==-1){       //本来y点不存在,或为根
65             if(node[y]==-1)                        //y原为根,现在少了一个根   
66                 rootNum--;
67             node[y]=x;                             //x成y的父结点                            
68             if(node[x]==0){                        //x若原来不存在,则成为新根,根数加1
69                 node[x]=-1;
70                 rootNum++;
71             }
72             if(y==x)                               //x=y的情况不合法                            
73                 isTree=false;
74             else{                                  //x!=y
75                 if(ishaveCircle(y))                     //有环:不是树
76                     isTree=false;          
77                 else                                    //无环:边数加1
78                     edgeNum++;             
79             }
80         }
81         else                                  //y原来已有父结点,现在变成有多个父结点,则不是树    
82             isTree=false;        
83     }
84     return 0;
85 }

 

分类:

技术点:

相关文章: