【八中*二叉树】这是一棵树吗?

来源:互联网 发布:excel查找不重复数据 编辑:程序博客网 时间:2024/05/01 08:21

这是一棵树吗?

时间限制: 1 Sec
内存限制: 64 MB

题目描述

树是一种重要的数据结构。它要么为空,要么是一个或多个顶点的集合,这些顶点由有向边连结,并且具有如下性质: (1) 有且仅有1个结点,称为“根”。根结点没有边指向它; (2) 除根结点,每个结点仅有一条边指向它; (3) 从根到每个结点仅有一条唯一的路径。 例如,下面三个图中,第一、二个表示的是树,第三个不是。
这里写图片描述
给出顶点和有向边的信息,编一个程序判断这是一棵树吗?

输入

输入包含多组数据,每组数据格式为:多组空格分开的整数对,每个整数对j, k(1≤j, k≤10000) 表示一条有向边从结点j指向结点k。两个空格分开的0,表示一组数据的结束。 最后一组数据后的两个空格分开的-1,表示所有输入数据的结束

输出

每组测试数据单独输出一行,输出”Case k is a tree.” 或者 “Case k is not a tree.” ,这里的k表示测试数据的组号,从1开始计数。

样例输入

6 8  5 3  5 2  6 45 6  0 08 1  7 3  6 2  8 9  7 57 4  7 8  7 6  0 03 8  6 8  6 45 3  5 6  5 2  0 0-1 -1

样例输出

Case 1 is a tree.Case 2 is a tree.Case 3 is not a tree.

提示

【初级*我的思路】

看到题目,我的初始想法就是按照题目的要求来做:首先,1) 有且仅有1个结点,称为“根”。根结点没有边指向它,那我们就可以判断有几个根,或是没有根。其次,2) 除根结点,每个结点仅有一条边指向它,可以判断每一个节点的所连边(用tot来储存),3) 从根到每个结点仅有一条唯一的路径(其实,我认为满足了第二个条件,是否第三个也满足了?【试试】)。

#include<cstdio>  #include<algorithm>#include<cstring>  using namespace std;int cx[10005],father[10005],a,minl,maxj,roots,f;  int main()  {      int i,j;      while(1)      {          f=0;          minl=10005;maxj=-1;          memset(cx,0,sizeof(cx));          memset(father,0,sizeof(father));          while(1)          {              scanf("%d%d",&i,&j);              if(i==-1) return 0;              if(!i) break;              if(minl>i||minl>j) minl=min(i,j);              if(maxj<i||maxj<j) maxj=(i,j); //Hi             cx[i]=cx[j]=1;              father[j]++;          }           roots=0;          for(i=minl;i<=maxj;i++)          {              if(cx[i]&&father[i]==0)              {                  roots++;                  if(roots>1)                  {                      f=1;                      break;                  }              }              if(cx[i]&&father[i]>1)              {                  f=1;                  break;              }          }          if(!roots) f=1;          if(f) printf("Case %d is not a tree.\n",++a);          else printf("Case %d is a tree.\n",++a);      }  }  

【改进】

遥看wrong红一片,仔细一看,才发现:原来我的max去哪了?又交,红得更惨了。

#include<cstdio>  #include<algorithm>#include<cstring>  using namespace std;int cx[10005],father[10005],a,minl,maxj,roots,f;  int main()  {      int i,j;      while(1)      {          f=0;          minl=10005;maxj=-1;          memset(cx,0,sizeof(cx));          memset(father,0,sizeof(father));          while(1)          {              scanf("%d%d",&i,&j);              if(i==-1) return 0;              if(!i) break;              if(minl>i||minl>j) minl=min(i,j);              if(maxj<i||maxj<j) maxj=max(i,j);              cx[i]=cx[j]=1;              father[j]++;          }           roots=0;          for(i=minl;i<=maxj;i++)          {              if(cx[i]&&father[i]==0)              {                  roots++;                  if(roots>1)                  {                      f=1;                      break;                  }              }              if(cx[i]&&father[i]>1)              {                  f=1;                  break;              }          }          if(!roots) f=1;          if(f) printf("Case %d is not a tree.\n",++a);          else printf("Case %d is a tree.\n",++a);      }  } 

【再改进】

妈啊,仔细想想,万一为空呢?它还是树吧。于是,我加上了……但没想到,我又wrong了。

#include<cstdio>  #include<algorithm>#include<cstring>  using namespace std;int cx[10005],father[10005],a,minl,maxj,roots,f;  int main()  {      int i,j;      while(1)      {          f=0;          minl=10005;maxj=-1;          memset(cx,0,sizeof(cx));          memset(father,0,sizeof(father));          while(1)          {              scanf("%d%d",&i,&j);              if(i==-1) return 0;              if(!i) break;              if(minl>i||minl>j) minl=min(i,j);              if(maxj<i||maxj<j) maxj=max(i,j);              cx[i]=cx[j]=1;              father[j]++;          }           if(minl>maxj)         {            printf("Case %d is not a tree.\n",++a);            continue;        }        roots=0;          for(i=minl;i<=maxj;i++)          {              if(cx[i]&&father[i]==0)              {                  roots++;                  if(roots>1)                  {                      f=1;                      break;                  }              }              if(cx[i]&&father[i]>1)              {                  f=1;                  break;              }          }          if(!roots) f=1;          if(f) printf("Case %d is not a tree.\n",++a);          else printf("Case %d is a tree.\n",++a);      }  } 

【终于明白,万物终和谐】

哎,还是自己的失误,写错了。

        if(minl>maxj)         {            printf("Case %d is not a tree.\n",++a);            continue;        }

献上AC代码:

#include<cstdio>   #include<algorithm> #include<cstring>   using namespace std; int cx[10005],father[10005],a,minl,maxj,roots,f;   int main()   {       int i,j;       while(1)       {           f=0;           minl=10005;maxj=-1;           memset(cx,0,sizeof(cx));           memset(father,0,sizeof(father));           while(1)           {               scanf("%d%d",&i,&j);               if(i==-1) return 0;               if(!i) break;               if(minl>i||minl>j) minl=min(i,j);               if(maxj<i||maxj<j) maxj=max(i,j);               cx[i]=cx[j]=1;               father[j]++;           }            if(minl>maxj)          {             printf("Case %d is a tree.\n",++a);             continue;         }         roots=0;           for(i=minl;i<=maxj;i++)           {               if(cx[i]&&father[i]==0)               {                   roots++;                   if(roots>1)                   {                       f=1;                       break;                   }               }               if(cx[i]&&father[i]>1)               {                   f=1;                   break;               }           }           if(!roots) f=1;           if(f) printf("Case %d is not a tree.\n",++a);           else printf("Case %d is a tree.\n",++a);       }   }  
原创粉丝点击