• Codeforces 902C/901A


    传送门:http://codeforces.com/contest/902/problem/C

    本题是一个关于“树”的问题。

    将一棵高度为h的有根树表示为数列{ai|i=0,1,2,...,h},其中ai是与根结点的距离为i的结点之数目。求:对于给定的数列,其对应的树的构型是否唯一?若不唯一,试构造两棵不同构的树,打印其特征数列{pi|i=1,2,...,n},其中,pii的父结点(若i为根结点,则pi为0)。

    首先,按照数列{a},将树分层:即第i层是与根结点距离为i的结点构成的集合。

    考虑在此约束下,一棵树出现异构的情形:当上下层结点存在连接的异构时,树出现异构。此时,上下层的节点数目均不唯一,即ai>1且ai-1>1。

    首先考虑树的一种构型X,这种构型是将下层的所有结点连接到上层的某一个结点上的。于是,这棵树上的所有结点,或者位于最长路径上,或者是连接在最长路径上的叶结点。例如:

     

    接下来首先讨论本题的案例,给定数列{1,2,2}。可以按照“构型X”构造树如下:

     

    这棵树的特征数列为{0,1,1,3,3},其一种“异构体”如下:

     

    可见,这个“异构体”是将原来的树删除边(3,4),再连接边(2,4)得到的。其特征数列为{0,1,1,2,3}。

    于是,对于一棵“构型X”的树,将其下层的一个结点与上层的一个叶结点构建边,即得到另一种构型的树。于是,可以得到树的两种构型。参考程序如下:

    #include <stdio.h>
    #define MAX_H 100001
    #define MAX_N 200001
    
    int a[MAX_H];
    int sum[MAX_H]; //prefix-sum.
    int p[2][MAX_N]; //parent of vertex.
    
    int main(void)
    {
        int h;
        scanf("%d", &h);
        for (int i = 0; i <= h; i++) {
            scanf("%d", &a[i]);
            //count prefix-sum.
            if (i) sum[i] = sum[i - 1];
            sum[i] += a[i];
        }
        int cur = 1;
        bool flag = true;
        p[0][1] = p[1][1] = 0;
        for (int i = 1; i <= h; i++) {
            for (int j = 0; j < a[i]; j++) {
                cur++;
                p[0][cur] = p[1][cur] = sum[i - 1];
            }
            if (a[i] > 1 && a[i - 1] > 1) {
                flag = false;
                p[1][cur]--;
            }
        }
        if (flag) printf("perfect
    ");
        else {
            printf("ambiguous
    ");
            for (int i = 0; i < 2; i++) {
                for (int j = 1; j <= sum[h]; j++)
                    printf("%d ", p[i][j]);
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    linux学习(三)输入输出重定向和管道功能、cat命令、more命令
    linux基础学习(二)ls命令以及文件访问权限例(-rw-r-r--)
    c语言的全排列
    linux基础学习(一)常用命令:date、pwd、cd、cal、who、wc等等
    用linux编译并运行c文件
    安装linux虚拟机
    安装quickLook插件以及解决如何不能读取offic问题
    java:数据结构(四)二叉查找树以及树的三种遍历
    java:数据结构复习(三)链表队列
    数据结构java学习(三)循环队列
  • 原文地址:https://www.cnblogs.com/siuginhung/p/8073159.html
Copyright © 2020-2023  润新知