NC24623 Tree Decoration

题目链接

题目

题目描述

Farmer John is decorating his Spring Equinox Tree (like a Christmas tree but popular about three months later). It can be modeled as a rooted mathematical tree with N (1 <= N <= 100,000) elements, labeled 1...N, with element 1 as the root of the tree. Each tree element e > 1 has a parent, PeP_ePe (1 <= \(P_e\) <= N). Element 1 has no parent (denoted '-1' in the input), of course, because it is the root of the tree.
Each element i has a corresponding subtree (potentially of size 1) rooted there. FJ would like to make sure that the subtree corresponding to element i has a total of at least \(C_i\) (0 <= \(C_i\) <= 10,000,000) ornaments scattered among its members. He would also like to minimize the total amount of time it takes him to place all the ornaments (it takes time K*\(T_i\) to place K ornaments at element i (1 <= \(T_i\)​ <= 100)).
Help FJ determine the minimum amount of time it takes to place ornaments that satisfy the constraints. Note that this answer might not fit into a 32-bit integer, but it will fit into a signed 64-bit integer.

For example, consider the tree below where nodes located higher on
the display are parents of connected lower nodes (1 is the root):

               1 
               |
               2
               |
               5
              / \
             4   3

Suppose that FJ has the following subtree constraints:

                  Minimum ornaments the subtree requires
                    |     Time to install an ornament
       Subtree      |       |
        root   |   C_i  |  T_i
       --------+--------+-------
          1    |    9   |   3
          2    |    2   |   2
          3    |    3   |   2
          4    |    1   |   4
          5    |    3   |   3

Then FJ can place all the ornaments as shown below, for a total
cost of 20:

            1 [0/9(0)]     legend: element# [ornaments here/ |                      total ornaments in subtree(node install time)]
            2 [3/9(6)]
            |
            5 [0/6(0)]
           / \
 [1/1(4)] 4   3 [5/5(10)]

输入描述

  • Line 1: A single integer: N
  • Lines 2..N+1: Line i+1 contains three space-separated integers: PiP_iPi, CiC_iCi, and TiT_iTi

输出描述

  • Line 1: A single integer: The minimum time to place all the ornaments

示例1

输入

5 
-1 9 3 
1 2 2 
5 3 2 
5 1 4 
2 3 3 

输出

20

题解

知识点:贪心,DFS,树形dp。

每个节点为根的子树都有一个最小要求的装饰数量,显然叶子节点只能全挂上去,随后向上考虑。对于一个子树,肯定把装饰挂在花费最小的节点上,因此可以回溯同时更新子树最小值,同时还需要一个记录已经挂了多少的数组。

注意结果可能超 int

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long

using namespace std;

struct edge {
    int to, nxt;
}e[100007];
int h[100007], cnt;
int root, c[100007], t[100007];///某节点的需求装饰;某子树所有节点的最小t;
ll ans, csum[100007];   ///某子树已有装饰

void add(int u, int v) {
    e[cnt].to = v;
    e[cnt].nxt = h[u];
    h[u] = cnt++;
}

void dfs(int u) {
    if (!~h[u]) {
        ans += c[u] * t[u];
        csum[u] = c[u];
        return;
    }
    for (int i = h[u];~i;i = e[i].nxt) {
        int v = e[i].to;
        dfs(v);
        csum[u] += csum[v];
        t[u] = min(t[u], t[v]);
    }
    ans += max(c[u] - csum[u], 0LL) * t[u];
    csum[u] = max(csum[u], 0LL + c[u]);
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    memset(h, -1, sizeof(h));
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) {
        int p;
        cin >> p >> c[i] >> t[i];
        if (p == -1) root = i;
        else add(p, i);
    }
    dfs(root);
    cout << ans << '\n';
    return 0;
}
posted @ 2022-07-16 15:08  空白菌  阅读(29)  评论(0编辑  收藏  举报