2017 Multi-University Training Contest

题解:

其实贪心地算就可以了

一个最优的分配就是每条边权贡献的值为min(k, sz[x]),sz[x]是指子树的大小

然后最后加起来就是答案。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <set>
#define fi first
#define se second
using namespace std;
const int maxn = 1e6 + 100;
typedef pair<long long, int> PLI;
typedef pair<int, long long> PIL;
vector<PIL> G[maxn];int sz[maxn], k;
long long ans = 0;
void dfs(int x, int fa){
    sz[x] = 1;
    for(auto e : G[x]){
        if(e.fi == fa) continue;
        dfs(e.fi, x);
        sz[x] += sz[e.fi];
        ans += min(k, sz[e.fi])*e.se;
    }
}

int main()
{
    int x, y, v, n;
    while(cin>>n>>k){
        ans = 0;
        for(int i = 1; i <= n; i++) G[i].clear();
        for(int i = 1; i < n; i++){
            scanf("%d %d %d", &x, &y, &v);
            G[x].push_back({y, v});
            G[y].push_back({x, v});
        }
        dfs(1, 1);
        cout<<ans<<endl;
    }
}
原文地址:https://www.cnblogs.com/Saurus/p/7271463.html