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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

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