[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=4033
[算法]
树形背包
时间复杂度 : O(N ^ 2)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 2010 typedef long long LL; struct edge { int to , w , nxt; } e[MAXN << 1]; int n , m , tot; int head[MAXN] , sz[MAXN]; LL dp[MAXN][MAXN]; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void addedge(int u , int v , int w) { ++tot; e[tot] = (edge){v , w , head[u]}; head[u] = tot; } inline void dfs(int u , int fa) { sz[u] = 1; dp[u][0] = dp[u][1] = 0; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (v == fa) continue; dfs(v , u); sz[u] += sz[v]; } int cnt = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to , w = e[i].w; if (v == fa) continue; cnt += sz[v]; for (int j = min(cnt , m); j >= 0; j--) { for (int k = 0; k <= min(sz[v] , j); k++) { if (dp[u][j - k] != -1) { LL value = 1LL * (k * (m - k) + (sz[v] - k) * (n - sz[v] - (m - k))) * w; dp[u][j] = max(dp[u][j] , dp[u][j - k] + dp[v][k] + value); } } } } } int main() { read(n); read(m); if (n - m < m) m = n - m; for (int i = 1; i < n; i++) { int u , v , w; read(u); read(v); read(w); addedge(u , v , w); addedge(v , u , w); } memset(dp , 255 , sizeof(dp)); dfs(1 , 0); printf("%lld " , dp[1][m]); return 0; }