考研机试题:这是一棵树吗

描述

树是一种众所周知的数据结构,它既可以是空的(null),也可以是一个节点或多个节点的集合,这些节点通过有向边连接且满足以下属性。

有且仅有一个节点,我们称之为根节点,没有任何有向边指向该节点。

除了根节点外,每个节点都有且仅有一条指向它的边。

从根节点到每个其他节点都有一条唯一的有向边序列。

例如,参考下图,节点用圆圈表示,有向边用带箭头的线表示,前两个图形是树,最后一个图形不是树。

给定若干个由有向边连接的节点集合的描述,请确定它们是否满足树的定义。

输入描述:

输入包含多组测试数据。

每组数据占若干行,包含若干个对于有向边的描述,每个有向边的描述包含两个整数 aa 和 bb,表示这条有向边从节点 aa 指向节点 bb。

当出现数对 0 0 时,表示这组数据的输入结束。

当出现数对 -1 -1 时,表示全部输入结束。

具体可参考样例。

输出描述:

每个数据输出占一行,表示结果。

格式为 Case k is a tree. 或 Case k is not a tree.,其中 kk 为组别编号,从 11 开始。

输入

6 8  5 3  5 2  6 4
5 6  0 0

8 1  7 3  6 2  8 9  7 5
7 4  7 8  7 6  0 0

3 8  6 8  6 4
5 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.

代码

#include<bits/stdc++.h>
using namespace std;

int fa[10010];

int main(){
    function<int(int)> find;
    find = [&](int a){ if(fa[a] != a) fa[a] = find(fa[a]);return fa[a];};

    for(int i = 1; ; i++){
        for(int i = 0; i < 10010; i++) fa[i] = i;

        int a, b, ok = 1, m = 0;
        bitset<10010> vis, ind;
        while(scanf("%d%d",&a, &b) && a > 0){
            if(ok){//
                if(find(a) == find(b)) ok = 0;//有回路
                else fa[fa[a]] = fa[b];
                vis[a] = 1, vis[b] = 1;//记录点数
                if(ind[b]) ok = 0; else ind[b] = 1;
                m++;//边的数量
            }
        }
        if(a == -1) break;
        if(m + 1 != vis.count() && m) ok = 0;//边数 + 1 = 点数才是树
        cout<<"Case "<<i<<" is "<<(ok ? "" : "not ")<<"a tree.\n";//输出
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值