NC51180 Accumulation Degree

题目链接

题目

题目描述

Trees are an important component of the natural landscape because of their prevention of erosion and the provision of a specific ather-sheltered ecosystem in and under their foliage. Trees have also been found to play an important role in producing oxygen and reducing carbon dioxide in the atmosphere, as well as moderating ground temperatures. They are also significant elements in landscaping and agriculture, both for their aesthetic appeal and their orchard crops (such as apples). Wood from trees is a common building material.

Trees also play an intimate role in many of the world's mythologies. Many scholars are interested in finding peculiar properties about trees, such as the center of a tree, tree counting, tree coloring. A(x) is one of such properties.

A(x) (accumulation degree of node x) is defined as follows:

  1. Each edge of the tree has an positive capacity.
  2. The nodes with degree of one in the tree are named terminals.
  3. The flow of each edge can't exceed its capacity.
  4. A(x) is the maximal flow that node x can flow to other terminal nodes.

Since it may be hard to understand the definition, an example is showed below:

img

A(1)=11+5+8=24
Details: 1->2 11
1->4->3 5
1->4->5 8(since 1->4 has capacity of 13)
A(2)=5+6=11
Details: 2->1->4->3 5
2->1->4->5 6
A(3)=5
Details: 3->4->5 5
A(4)=11+5+10=26
Details: 4->1->2 11
4->3 5
4->5 10
A(5)=10
Details: 5->4->1->2 10

The accumulation degree of a tree is the maximal accumulation degree among its nodes. Here your task is to find the accumulation degree of the given trees.

输入描述

The first line of the input is an integer T which indicates the number of test cases. The first line of each test case is a positive integer n. Each of the following n - 1 lines contains three integers x, y, z separated by spaces, representing there is an edge between node x and node y, and the capacity of the edge is z. Nodes are numbered from 1 to n.
All the elements are nonnegative integers no more than 200000. You may assume that the test data are all tree metrics.

输出描述

For each test case, output the result on a single line.

示例1

输入

1
5
1 2 11
1 4 13
3 4 5
4 5 10

输出

26

题解

知识点:树形dp。

显然树形dp,二次扫描+换根。

第一次先预处理出每个子树的流量最大值,设 \(f[u]\) 为以 \(u\) 为根的子树的流量最大值。转移方程为:

\[f[u] = \sum \left \{ \begin{aligned} &\min (f[v_i],w_{v_i}) & &,v_i不是叶子节点\\ &w_{v_i} & &,v_i是叶子节点 \end{aligned} \right. \]

第二次处理出每个点对于整棵树的最大值,设 \(ff[u]\) 为以 \(u\) 为源点的流量最大值。转移方程为:

\[ff[v] = f[v] + \left \{ \begin{aligned} &w_v & &,u是叶子节点\\ &\min(ff[u] - w_v, w_v) & &,v是叶子节点\\ &\min(ff[u] - \min(f[v], w_u), w_u)& &,otherwise \end{aligned} \right. \]

具体原因注释里写着。

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

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

代码

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

using namespace std;

vector<pair<int, ll>> g[200007];
ll f[200007];

void dfs1(int u, int fa) {
    for (auto [v, w] : g[u]) {
        if (v == fa) continue;
        dfs1(v, u);
        f[u] += g[v].size() == 1 ? w : min(f[v], w);///叶子节点可以直接贡献,因此直接加
    }
}

void dfs2(int u, int fa) {
    for (auto [v, w] : g[u]) {
        if (v == fa) continue;
        if (g[u].size() == 1) f[v] += w;///如果父节点是一个叶节点,可以直接贡献,不需要考虑其到其他子树流量为0
        else if (g[v].size() == 1) f[v] += min(f[u] - w, w);///否则如果自己是一个叶节点,自己支路流量应该直接是w,而不能min(f[v],w)
        else f[v] += min(f[u] - min(f[v], w), w);///否则大家都不是叶子节点,则总贡献=子树内贡献+min(父节点总贡献-子树实际贡献,边权)
        dfs2(v, u);
    }
}

bool solve() {
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) g[i].clear(), f[i] = 0;
    for (int i = 1;i < n;i++) {
        int u, v, w;
        cin >> u >> v >> w;
        g[u].push_back({ v,w });
        g[v].push_back({ u,w });
    }
    dfs1(1, 0);
    dfs2(1, 0);
    ll ans = 0;
    for (int i = 1;i <= n;i++) ans = max(ans, f[i]);
    cout << ans << '\n';
    return true;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        if (!solve()) cout << -1 << '\n';
    }
    return 0;
}
posted @ 2022-08-25 14:12  空白菌  阅读(18)  评论(0编辑  收藏  举报