## Maximum weighted edge independent set

It's really a hand speed field. It belongs to yes. I can only say that I'm lucky. No wa, Jinwei

Laishui blog

At that time, there was a mistake. Of course, some strings were unfamiliar. When I saw J, I felt like a tree dp. Although I couldn't figure out the details in the game, the general direction was really right. I enumerated and replaced several edges, and then the tree dp was hanged on a tree(

It's too late. Keep going qaq

Don't write the meaning of the Chinese question

The official caption is well written:

Enumerate the number T of edges with added edge weight p located on the final edge independent set, then 0 ≤ t ≤ k and 2t ≤ n, because each edge will occupy two points in the graph. Assuming that t edges are to be added finally, 2t points need to be deleted from the graph, and then use T × p + the maximum weighted edge independent set of the remaining graph to update the answer, which is equivalent to specifying 2t points on the tree that do not match other points, and then calculating the weighted maximum match of the tree. Use bottom-up tree dynamic programming to solve this problem: Let f[i][j][0] Represents the maximum weighted matching when the subtree of point I is considered, j points are deleted from the subtree of point I, and I cannot match the father of I upward; Let f[i][j][1] represent the maximum weighted matching when the subtree of point I is considered, j points are deleted from the subtree of point I, and I can match the father of I upward. Then the number of States is O(nk) , the information of two subtrees needs to be merged during the transfer. The time complexity of j can be guaranteed to be O(nk) by enumerating from 0 to min(sizex, k), where sizex represents the current subtree size of x.

About merging subtrees, I always thought that the chrysanthemum diagram would crack. It turned out that it was merged like this. What am I, bu

Initialization“

#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll N = 1e5 + 10; const ll M = 210; // Double the number of edges const ll inf = 0x3f3f3f3f3f3f3f3f; struct node { ll to; ll len; }; vector<node> g[N]; ll n, k; ll p; ll f[N][M][2], tmp[M][2]; ll sz[N]; // f[i][j][0]: = j points are mismatched on the subtree with I as the node (including I), and I has no matching maximum weight matching // f[i][j][1]: = j points are mismatched on the subtree with I as the node (including I), and the maximum weight of I matching matches void dfs(ll x, ll p) { sz[x] = 1; f[x][0][0] = 0; f[x][1][1] = 0; for (auto uu : g[x]) { ll to = uu.to; ll len = uu.len; if (to == p) continue; dfs(to, x); for (ll i = 0; i <= k * 2; ++i) { tmp[i][0] = f[x][i][0]; tmp[i][1] = f[x][i][1]; } for (ll i = 0; i <= min(sz[x], k * 2); ++i) { for (ll j = 0; j <= min(sz[to], k * 2); ++j) { if (i + j > 2ll * k) continue; tmp[i + j][0] = max(tmp[i + j][0], f[x][i][0] + max(f[to][j][0], f[to][j][1])); tmp[i + j][1] = max(tmp[i + j][1], f[x][i][1] + max(f[to][j][0], f[to][j][1])); tmp[i + j][1] = max(tmp[i + j][1], f[x][i][0] + f[to][j][0] + len); } } for (ll i = 0; i <= min(sz[x], k * 2); ++i) { for (ll j = 0; j <= min(sz[to], k * 2); ++j) { f[x][i + j][0] = tmp[i + j][0]; f[x][i + j][1] = tmp[i + j][1]; } } sz[x] += sz[to]; } } signed main() { scanf("%lld%lld%lld", &n, &k, &p); ll len; for (ll i = 0, u, v; i < n - 1; ++i) { scanf("%lld%lld%lld", &u, &v, &len); g[u].push_back({v, len}); g[v].push_back({u, len}); } ll mn = min(n, k * 2); for(int i = 0 ;i <= n; ++ i) { for(int j = 0; j <= mn; ++ j ) { f[i][j][0] = -inf; f[i][j][1] = -inf; } } dfs(1, -1); ll ans = 0; for (ll i = 0; i <= mn; ++i) { ans = max(ans, max(f[1][i][0], f[1][i][1]) + (ll) i / 2 * p); } printf("%lld", ans); return 0; }