A tree is divided into several parts, one of which has a node of P. To be honest, the above operations should delete at least a few sides.
Practice: tree-shaped backpack. Establish the root node and find out the number of children of each node. To solve this problem, we first establish each subtree as a State and establish a state equation: DP [u] [J] = min (DP [u] [J-K] + dp [v] [k]), where j k represents U, V indicates the number of edges to be deleted from a tree rooted in U. Here DP [u] [son [u] = 0. This formula is only valid when u has a parent node. It is a tree composed of its parent node, delete son [u]
Node. You only need to delete the edge of the link and the U. Another problem is that each node needs to be traversed when the answer is finally generated. Besides the total ancestor nodes, in order to form a sub-tree independently, the Dp value of other nodes must be increased by 1.
# Include <stdio. h> # include <string. h> # define EPS 1e8 # define LMT 155/* for similar questions, you must first establish the root node */typedef struct {int U, V, next;} line; line E [LMT <1]; int DP [LMT] [LMT], next [LMT], son [LMT]; int all, P, N; inline int min (int A, int B) {return a <B? A: B;} void insert (INT U, int v) {e [all]. U = u; E [all]. V = V; E [all]. next = next [u]; next [u] = All ++; E [all]. U = V; E [all]. V = u; E [all]. next = next [v]; next [v] = All ++;} void inidfs (int u, int pre) {son [u] = 1; int V, X; for (x = next [u]; X! =-1; X = E [X]. Next) if (E [X]. V! = Pre) {v = E [X]. v; inidfs (v, U); son [u] + = Son [v];} DP [u] [son [u] = 1; DP [u] [0] = 0;} void DFS (int u, int pre) {int X, V, J, K; For (x = next [u]; x! =-1; X = E [X]. Next) if (E [X]. V! = Pre) {v = E [X]. v; DFS (v, U); For (j = Son [u]-1; j> = 0; j --) for (k = 0; k <= Son [v] & K <= J; k ++) if (DP [u] [J-K]! = EPS) DP [u] [J] = min (DP [u] [J], DP [u] [J-K] + dp [v] [k]) ;}} int main () {int I, ANS, J; while (scanf ("% d", & N, & P )! = EOF) {memset (next,-1, sizeof (next); memset (son, 0, sizeof (son); All = 0; for (I = 1; I <n; I ++) {int U, V; scanf ("% d", & U, & V); insert (u, v );} for (I = 1; I <= N; I ++) for (j = 0; j <= N; j ++) DP [I] [J] = EPS; inidfs (1, 0); DFS (1, 0); ans = DP [1] [son [1]-p]; for (I = 2; I <= N; I ++) if (son [I]> = P) ans = min (ANS, DP [I] [son [I]-p] + 1 ); printf ("% d \ n", ANS);} return 0 ;}