You can use F [I] [J] to indicate that the optimal solution of the J branches is retained when the node is recursive to the I node. When making a decision, you can only select from a subtree, or select from two subtree at the same time, andIf you select the branches in a subtree, You must select the branches connected to the subtree.
# Include <stdio. h> # Include < String . H> # Define Maxd 110 # Define Maxm 210 Int N, Q, E, first [maxd], next [maxm], V [maxm], W [maxm], F [maxd] [maxd]; Void Add ( Int X, Int Y,Int Z) {v [E] = Y, W [e] = Z; next [E] = First [X], first [x] = e ++ ;} Void Init (){ Int I, J, K, x, y, z; memset (first, - 1 , Sizeof (First); e = 0 ; For (I =1 ; I <n; I ++ ) {Scanf ( " % D " , & X, & Y ,& Z); add (x, y, z); add (Y, x, z );}} Void DFS ( Int Cur, Int FA ){ Int I, j, n = 0 , G [ 2 ], Num [ 2 ]; For (I = first [cur]; I! =- 1 ; I = Next [I]) If (V [I]! = FA) {G [N] = V [I], num [N] = W [I]; ++ N; DFS (V [I], cur );} If (N = 1 ){ For (I = 1 ; I <= Q; I ++ ) F [cur] [I] = F [G [ 0 ] [I- 1 ] + Num [ 0 ];} Else If (N = 2 ) {F [cur] [ 1 ] = Num [ 0 ]> Num [ 1 ]? Num [ 0 ]: Num [1 ]; For (I = 2 ; I <= Q; I ++ ){ For (J = 0 ; J < 2 ; J ++ ) If (F [G [J] [I- 1 ] + Num [J]> F [cur] [I]) f [cur] [I] = F [G [J] [I- 1 ] +Num [J]; For (J = 0 ; J <= I- 2 ; J ++ ) If (F [G [ 0 ] [J] + num [ 0 ] + F [G [ 1 ] [I- 2 -J] + num [ 1 ]> F [cur] [I]) f [cur] [I] = F [G [ 0 ] [J] + num [ 0 ] + F [G [ 1 ] [I- 2 -J] + num [ 1 ] ;}}} Void Solve () {memset (F, 0 , Sizeof (F); DFS ( 1 ,- 1 ); Printf ( " % D \ n " , F [ 1 ] [Q]);} Int Main (){ While (Scanf ( " % D " , & N, & Q) = 2 ) {Init (); solve ();} Return 0 ;}