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
原文地址:https://www.cnblogs.com/19992147orz/p/12258537.html