码迷,mamicode.com
首页 > 其他好文 > 详细

[CF1223E] Paint the Tree - 树形dp

时间:2021-02-19 12:59:37      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:没有   paint   注意   cto   跳过   等于   func   pre   ever   

## [CF1223E] Paint the Tree - 树形dp

### Description

在树上选取一些边,保证没有点度超过 k,求最大边权和

### Solution

用 $f[i][0/1]$ 表示处理了 i 的子树,i 的度小于等于 k 或 k-1 时的最大答案

注意在跳过边权 <0 的边

``` cpp
#include <bits/stdc++.h>
using namespace std;

#define int long long

void solve()
{
    int n, k;
    cin >> n >> k;
    vector<vector<pair<int, int>>> g(n + 2);
    vector<vector<int>> f(n + 2, vector<int>(2));

    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});
    }

    function<void(int, int)> dfs = [&](int p, int from) -> void {
        vector<int> vec;
        int sum = 0;
        for (auto [q, w] : g[p])
            if (q != from)
            {
                dfs(q, p);
                vec.push_back(f[q][1] + w - f[q][0]);
                sum += f[q][0];
            }
        sort(vec.begin(), vec.end());
        reverse(vec.begin(), vec.end());
        int first_k = 0, first_km1 = 0;
        for (int i = 0; i < k && i < vec.size() && vec[i] > 0; i++)
            first_k += vec[i];
        for (int i = 0; i + 1 < k && i < vec.size() && vec[i] > 0; i++)
            first_km1 += vec[i];
        f[p][0] = sum + first_k;
        f[p][1] = sum + first_km1;
    };

    dfs(1, 0);

    int ans = 0;
    for (int i = 1; i <= n; i++)
        ans = max(ans, max(f[i][0], f[i][1]));
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);

    int t;
    cin >> t;
    while (t--)
        solve();
}

[CF1223E] Paint the Tree - 树形dp

标签:没有   paint   注意   cto   跳过   等于   func   pre   ever   

原文地址:https://www.cnblogs.com/mollnn/p/14408458.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!