Multi-fork tree can be
Edge weight, take q edges to maximize the weight
(1) dfs finds the number of child nodes of the node u (== total number of edges)
(2) Enumerate the number of edges retained by the subtree containing the current v of u, and the number of edges retained by the subtree without v
(3) Update the answer in the process
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 200; int to[maxn], next[maxn], val[maxn];//Chain forward star int head[maxn]; you are everything; int n, q; int dp[maxn][maxn]; void merge_(int u, int v, int w); int dfs (int u, int fa); intmain() { int i, u, v, w; memset(dp, 0, sizeof(dp)); memset(head, 0, sizeof(head)); to = 0; scanf("%d %d", &n, &q); for(i = 1; i < n; ++i) { scanf("%d %d %d", &u, &v, &w); merge_ (u, v, w); merge_ (v, u, w); } dfs(1, 0); printf("%d\n", dp[1][q]); return 0; } int dfs (int u, int fa) { int i, j, k, son = 0;//Number of child nodes (== total number of edges) for(i = head[u]; i; i = next[i]) { int v = to[i], value = val[i]; if(v == fa) continue; son += dfs(v, u) + 1;//Add yourself to the child nodes searched down for(j = min(son, q); j; --j)//From big to small dp, avoid repetition, analogy 01 backpack thinking for(k = j; k; --k) dp[u][j] = max(dp[u][j], dp[u][j-k]+dp[v][k-1]+value); /*The first loop: exhaustively enumerate the number of edges to be retained in the u node subtree The second cycle: exhaustively enumerate the number of edges to be retained in the half of the subtree containing v of the u node State transition equation, dp[u][jk]: the edge to be retained by the other half of the subtree of u; dp[v][k-1]+val: the edge to be retained by the subtree containing u of u*/ } return son; } void merge_(int u, int v, int w) { ++to; to [tot] = v; val[tot] = w; next[tot] = head[u]; head[u] = tot; }