zoukankan      html  css  js  c++  java
  • Codeforces 1311E Construct the Binary Tree

    Description

    要求构造一个 $n$ 个节点的二叉树(每个节点拥有不超过 $2$ 个孩子),节点 $1$ 为根,要使所有节点到根的距离之和为 $d$ 。要求先判断可不可以构造,如果可以输出 YES,下一行输出 $2$ 到 $n$ 号节点的父亲节点,否则输出 NO。有多组询问。

    Solution

    首先,我们可以先确定可行的 $d$ 的范围。

    显然,当二叉树是一条链的时候,$d$ 是最大的,也就是说,$0+1+2+cdots (n-1) = d_{max}$,稍微转化一下,就是 $d le frac{n(n-1)}{2}$。

    而把这颗二叉树给尽量满的构造 $d$ 显然是最小的,也就是说,确保这棵二叉树是完全二叉树,就可以得到 $d_{min}$,这个不妨递推一下,如果用 $dep_i$ 表示第 $i$ 个结点的深度,那么显然有 $dep_{2i} = dep_i + 1, dep_{2i+1} = dep_i + 1$(类比线段树很容易理解),当然,这个和 $dep_i = dep_{lfloorfrac i 2 floor}+1$ 是等价的。

    那么在 $[d_{min}, d_{max}]$ 之间的 $d$ 都是可行的了,观察到 $n, d$ 都很小,可以尝试一步步的转移。先构造出一棵完全二叉树,每次 找到一个可行的深度最大的点,把它向下移动一层

    为了实现方便,不妨把 $dep = i$ 的点存到一个 vector 中,名字叫做 $ ext{node}_i$,现在试图把某一个 $dep = i$ 的点下移,要求显然就是 去掉这个点后,下面一层还有位置,可以表现为 $operatorname{size}( ext{node}_{i+1})<(operatorname{size}( ext{node}_i) - 1) imes 2$,暴力下移即可。

    最后我们得到的是若干个 vector 数组,令 $ ext{node}_{i,j}$ 的儿子是 $ ext{node}_{i+1,2i}$ 和 $ ext{node}_{i+1,2i+1}$ 就行了(当然,前提是存在)。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 5005;
    int n, dep[N], d, mxdep, sumdep, fa[N];
    vector<int> node[N];
    int main()
    {
        int t;
        cin >> t;
        while(t--)
        {
            cin >> n >> d;
            for(int i = 1; i <= n; i++) node[i].clear();
            dep[1] = mxdep = sumdep = 0;
            node[0].push_back(1);
            for(int i = 2; i <= n; i++)
            {
                dep[i] = dep[i >> 1] + 1;
                sumdep += dep[i];
                mxdep = max(mxdep, dep[i]);
                node[dep[i]].push_back(i); 
            }
            if(d < sumdep || d > n * (n - 1) / 2)
            {
                cout << "NO
    ";
                continue;
            }
            while(sumdep < d)
            {
                for(int i = mxdep; ~i; i--)
                {
                    if(node[i].size() >= 2 && node[i + 1].size() < node[i].size() * 2 - 2)
                    {
                        sumdep++;
                        mxdep = max(mxdep, i + 1);
                        node[i + 1].push_back(node[i].back());
                        node[i].pop_back();
                        break;
                    }
                }
            }
            for(int i = 0; i <= mxdep; i++)
            {
                for(int j = 0; j < node[i].size(); j++)
                {
                    int ls = j * 2, rs = j * 2 + 1;
                    if(ls < node[i + 1].size()) fa[node[i + 1][ls]] = node[i][j];
                    if(rs < node[i + 1].size()) fa[node[i + 1][rs]] = node[i][j];
                }
            }
            cout << "YES" << endl;
            for(int i = 2; i <= n; i++) cout << fa[i] << ' ';
            cout << endl;
        }
    }
  • 相关阅读:
    [ USACO 2018 OPEN ] Out of Sorts (Platinum)
    [ USACO 2018 OPEN ] Out of Sorts (Gold)
    [ USACO 2018 OPEN ] Out of Sorts (Silver)
    [ BZOJ 4236 ] JOIOJI
    [ HAOI 2012 ] 容易题
    [ HAOI 2008 ] 玩具取名
    「BZOJ 4502」串
    Codeforces 493 E.Devu and Birthday Celebration
    「TJOI 2018」教科书般的亵渎
    「TJOI 2018」游园会 Party
  • 原文地址:https://www.cnblogs.com/syksykCCC/p/CF1311E.html
Copyright © 2011-2022 走看看