zoukankan      html  css  js  c++  java
  • CF1311E Construct the Binary Tree

    题面

    给定树的节点数n和d,构造一颗二叉树,使所有节点的的深度和为d

    容易得出n个节点的二叉树每个节点深度的总和最大为n*(n-1)/2,最小值为满二叉树的情况

    于是就可以愉快地判断答案是否存在啦,然后还得构造出一个合法的答案qwq

    我的方法是先弄成一条链再进行调整

    反正数据不大,不如简单点每次只调整一个 没有儿子 的节点,使其深度减少1(用c数组表示一个节点的儿子个数)

    具体做法就是先枚举一个没有儿子的节点x,然后枚举一个儿子不满且深度比x小2的节点y,将x移动为y的儿子,移动后要更新一些信息(看代码)

    这样做看似复杂度爆炸(n^3),但事实上由于数据范围的约束,当n较大时d无法满足大于可能最小值的条件,并不用执行之后复杂度爆炸的过程 >_<

    稍稍优化一下,如果一个节点已经无法移动(深度更小的位置已经满了),就做一个标记,避免下次又选到这个点做无用功

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 5;
    int dep[N], fa[N], c[N], k[N];
    signed main() {
        int t; scanf ("%d", &t);
        while (t--) {
            int n, d; scanf ("%d %d", &n, &d);
            if (d > n * (n - 1) / 2) { puts ("NO"); continue; }
            int tmp = n - 1, mn = 0;
            for (int i = 1; ; ++i) {
                if (tmp < (1 << i)) { mn += i * tmp; break; }
                tmp -= (1 << i), mn += i * (1 << i);
            } if (d < mn) { puts ("NO"); continue; } puts ("YES");
            for (int i = 1; i <= n; ++i)
                fa[i] = i - 1, dep[i] = i - 1, c[i] = 1, k[i] = 0; c[n] = 0;
            int now = n * (n - 1) / 2;
            while (now > d) {
                int p, ok = 0, tmp;
                for (int i = 1; i <= n; ++i) if (!k[i] && !c[i]) { p = i; break; }
                for (int i = 1; i <= n; ++i)
                    if (c[i] < 2 && dep[i] == dep[p] - 2) { tmp = i; ok = 1; break;}
                if (!ok) { k[p] = 1; continue; }    //如果节点已经无法移动就打个标记,防止TLE
                --c[fa[p]], ++c[tmp], --dep[p], fa[p] = tmp, --now;  //更新节点信息
            } for (int i = 2; i <= n; ++i) printf ("%d ", fa[i]); puts ("");
        } return 0;
    }
    
  • 相关阅读:
    Win7操作系统防火墙无法关闭的问题 无法找到防火墙关闭的地方的解决的方法
    【微信】微信获取TOKEN,以及储存TOKEN方法,Spring quartz让Token永只是期
    OC内存管理总结,清晰明了!
    下次自己主动登录(记住password)功能
    linux删除svn版本号库
    Python中可避免读写乱码的一个强慷慨法
    Tomcat源代码阅读#1:classloader初始化
    iOS关于图片点到像素转换之杂谈
    hdu 3804树链剖分+离线操作
    cdn缓存
  • 原文地址:https://www.cnblogs.com/whx666/p/12670503.html
Copyright © 2011-2022 走看看