Is It A Tree?

A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties.There is exactly one node, called the root, to which no directed edges point.Every node except the root has exactly one edge pointing to it.There is a unique sequence of directed edges from the root to each node.For example, consider the illustrations below, in which nodes are represented by circles and edges are represented by lines with arrowheads. The first two of these are trees, but the last is not.

In this problem you will be given several descriptions of collections of nodes connected by directed edges. For each of these you are to determine if the collection satisfies the definition of a tree or not.

Input
The input will consist of a sequence of descriptions (test cases) followed by a pair of negative integers. Each test case will consist of a sequence of edge descriptions followed by a pair of zeroes Each edge description will consist of a pair of integers; the first integer identifies the node from which the edge begins, and the second integer identifies the node to which the edge is directed. Node numbers will always be greater than zero.

Output
For each test case display the line "Case k is a tree." or the line "Case k is not a tree.", where k corresponds to the test case number (they are sequentially numbered starting with 1).

Sample Input
6 8 5 3 5 2 6 45 6 0 0
8 1 7 3 6 2 8 9 7 57 4 7 8 7 6 0 0
3 8 6 8 6 45 3 5 6 5 2 0 0
-1 -1

Sample Output
Case 1 is a tree.
Case 2 is a tree.
Case 3 is not a tree.
别看这道题的英文复杂,实际上题意真的简单,题意如下:
就样例来说,每两个数字代表一条边的两端,也就是说这两个数字代表一条边,0 0代表一组数据的结束,-1 -1代表程序结束。
这一道题的目的就是为了判断一下这些数字到底能不能组成一棵树。
我们要知道,要组成一颗树呢,首先,要没有环(你见过一颗树有环的吗,反正我是没有),其次,这棵树只能有一个根节点(有两个及以上的根节点,这就不是树了,是森林了),最后,一个点的入度最多为1(如果入度大于1了,那这些数构成的不是有森林就是有环了),根节点入度为0。
还有,我们要注意一个坑点,空树也是一棵树,也就是说直接给你一个0 0,这就是一个树。
你们可能注意到我的写法里面用了一下宏定义,其实适当的运用宏定义不仅使得代码的意思更好理解,还可以优化我们的代码。
这道题呢我是用并查集做的,不用并查集其实也能做。
代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
#define cls(x) memset(x,0,sizeof(x))//代表清空一个数组
using namespace std;
const int MAXN=100010;
const int inf=1<<29;
bool flag=false;
int Min,Max;//这里的Min和Max代表得是点的大小范围
int par[MAXN],in[MAXN];
bool exi[MAXN];//判断一个点是否存在
int find(int x)
{
    if(par[x]==x)return x;
    return par[x]=find(par[x]);
}
void init()
{
    for(int i=1;i<=MAXN;i++)
     par[i]=i;
}
void unite(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y){
        flag=true;//判断是否有环
        return ;
    }
    par[y]=x;
}
bool solve()
{
    int cnt=0;
    for(int i=Min;i<=Max;i++)
    if(exi[i])
    {
        if(in[i]==0)cnt++;//判断根结点
        if(in[i]>1)return false;//判断是否有入度大于1的点
    }
    if(cnt!=1)return false;
    return true;
}
int main()
{
    int a,b;
    Min=inf,Max=-1;
    int p=1;
    init();
    while(~scanf("%d%d",&a,&b))
    {
        if(a==-1&&b==-1)return 0;
        if(a==0 && b==0)
        {
         if(Min==inf&&Max==-1){
            printf("Case %d is a tree.\n",p++);
            continue;
         }
         bool ans=solve();
         if(ans && !flag)printf("Case %d is a tree.\n",p++);
         else printf("Case %d is not a tree.\n",p++);
         cls(in);
         cls(par);
         cls(exi);
         Min=inf;
         Max=-1;
         init();
         flag=false;
         continue;
        }
        in[b]++;
        if(Max<a)Max=a;//确定点范围
        if(Max<b)Max=b;
        if(Min>a)Min=a;
        if(Min>b)Min=b;
        exi[a]=true;
        exi[b]=true; 
        unite(a,b);
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 今天在BM南京营学习到了职业生涯规划的一些理论,包括人职模型以及能力三核,其中人职模型比较复杂,而能力三核的理论稍...
    我就是哈哈哈阅读 7,823评论 2 1
  • 谁爱这不息的变幻, 她的行径? 催一阵急雨, 抹一天云霞, 月亮,星光,日影, 在在都是她的花样, 更不容峰峦与江...
    丹青墨笔阅读 1,950评论 0 1
  • 国庆节,在这个举国同庆的日子,多少年前的这一天,一位老人宣布中华人民共和国成立了!是多么的富有划时代的意义!从此,...
    想飞的树不如草阅读 3,638评论 0 3
  • 我们的饮食可分为食品和饮品两大类。饮品在人类的饮食结构中发挥着食品不能替代的作用。从人们最先接触的饮品——水开始,...
    久九商会阅读 3,244评论 0 0
  • 谎言是美是丑,其实取决于我们看待问题的方式。同样的谎言,也许是美的同时,也是丑陋的。 有些所谓的善意谎言,也许最终...
    子耳子耳阅读 4,822评论 0 0

友情链接更多精彩内容