• 1240C


    贪心想了两个小时 想到怀疑人生

    其实是一个简单的$dp$

    $dp[i][0]$表示不选父边

    $dp[i][1]$表示选

    那么儿子排个序贪心一下就行了

    感觉头铁总是会凉 一个想法不行要尝试换一下

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int maxn = 5e5 + 5;
    int n, k;
    ll dp[maxn][2];
    vector<pair<int, int> > G[maxn];
    void dfs(int u, int f) {
        vector<ll> vec;
        for(auto [v, w] : G[u]) {
            if(v != f) {
                dfs(v, u);
                dp[v][1] += w;
                dp[u][1] += dp[v][0];
                if(dp[v][1] > dp[v][0]) {
                    vec.push_back(dp[v][1] - dp[v][0]);
                }
            }
        }
        sort(vec.begin(), vec.end(), greater<ll>());
        for(int i = 0; i < min(k - 1, (int)vec.size()); ++i) {
            dp[u][1] += vec[i];
        }
        dp[u][0] = dp[u][1];
        if(vec.size() >= k) {
            dp[u][0] += vec[k - 1];
        }
    }
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &k);
            for(int i = 1; i <= n; ++i) {
                dp[i][0] = dp[i][1] = 0;
                G[i].clear();
            }
            for(int i = 1; i < n; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                G[u].emplace_back(v, w);
                G[v].emplace_back(u, w);
            }
            dfs(1, 0);
            // dp[u][0 / 1] : the maximum value that whether we leave an edge for node u's father or not 
            printf("%lld
    ", dp[1][0]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    BZOJ 4025: 二分图
    20180803 题解 Winniechen's Tesst
    前尘浮华一场梦 NOI2018 游记
    UOJ#311. 【UNR #2】积劳成疾
    欢迎到我的新Blog!
    弹飞大爷 BZOJ4764 LCT维护内向基环树森林
    [SCOI2007]修车 BZOJ1070
    KD-Tree
    CDQ分治
    深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台
  • 原文地址:https://www.cnblogs.com/19992147orz/p/12258537.html
Copyright © 2020-2023  润新知