Codeforces Round #612 (Div. 1) B Numbers on Tree(dfs+思维)
发布日期:2021-05-08 15:13:55 浏览次数:17 分类:精选文章

本文共 1452 字,大约阅读时间需要 4 分钟。

构造符合条件的权值序列方法解析

定义Ci为i点子树中权值比i小的结点个数,给定每个节点的Ci值,我们需要构造出符合条件的权值序列。本文将详细介绍相关方法和实现思路。

方法概述

构造权值序列的关键在于确定每个节点的权值与其子树排名之间的关系。通过对节点进行深度优先搜索(DFS),我们可以构建每个节点的子树排名序列。将这些排名依据Ci值进行插入,最终得到符合条件的权值序列。

核心实现思路

  • 排名序列构造

    对于每个节点x,首先构造其子树的排名序列。将所有子树中的节点按预定规则进行排序,形成一个排名序列。这个过程可以通过递归DFS实现。

  • 节点插入位置确定

    根据Ci值,确定每个节点在其子树排名序列中的插入位置。例如,假设节点4的Ci值为2,其子树排名序列为2、5、3。根据Ci=2的定义,节点4应插入排名5后面。

  • 递归插入过程

    通过递归的方式将所有节点按照规则插入到各自的排名序列中。确保每一步插入操作均符合Ci的定义,避免违反权值关系。

  • 代码实现

    #include 
    #include
    using namespace std;
    const int maxn = 2e4 + 1;
    int n, a, root, num[maxn], ans[maxn];
    vector
    > v(maxn + 1);
    void dfs(int x) {
    vector
    temp;
    for (int to : v[x]) {
    temp = dfs(to);
    for (int val : temp) {
    rank.push_back(val);
    }
    }
    if (num[x] > rank.size()) {
    printf("NO");
    exit(0);
    }
    rank.insert(rank.begin() + num[x], x);
    return rank;
    }
    int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
    scanf("%d %d", &a, &num[i]);
    if (a == 0) {
    root = i;
    } else {
    v[a].push_back(i);
    }
    }
    vector
    range = dfs(root); // 以下为权值序列生成逻辑 }

    代码解释

  • 递归函数dfs

    该函数负责构造子树排名序列。首先递归处理所有子节点,生成各子树的排名序列。然后将这些序列合并到当前节点的排名中。

  • 节点插入

    在返回路径时,根据节点的Ci值(num[x])插入到当前排名序列的适当位置。确保插入位置不违反权值关系。

  • 主程序逻辑

    读取输入数据,初始化节点信息。调用DFS构造权值序列。通过递归插入,生成最终的权值序列。

  • 这种方法确保了每个节点的权值与其子树排名关系准确无误,符合Ci的定义。通过DFS递归实现,保证了代码的高效性和正确性。

    上一篇:Codeforces Round #609 (Div. 1) B. Domino for Young (思维)
    下一篇:牛客练习赛56 D 小翔和泰拉瑞亚(线段树)

    发表评论

    最新留言

    路过,博主的博客真漂亮。。
    [***.116.15.85]2025年04月11日 23时26分08秒