background
\ (Luogu \) \ (P1122 / Codevs5565 \)
The meaning of problems
Given a \ (n-\) to nodes \ (1 \) dots as the root node of the tree \ (n-1 \) sides and weight \ ((x_i, y_i, W_i) \) , left after seeking to cut some of the branches \ (q \) maximum side and right edges.
solution
Nor is it a tree \ (dp \) template. Or exercises.
Because the tree is a binary tree, there is a beautiful nature: trees within a sub-tree branches reservations can only get around by the sub-tree (this is not bullshit you).
Considering the meaning of problems left conversion, some of the cut branches \ (Q \) edges i.e. left \ (q + 1 \) point and must contain the root.
Thus it can be set \ (f_ {x, i} \) represented by \ (X \) node subtree rooted left \ (I \) maximum points and edge weights.
This time it should continue to consider the topic of conversion. Because the root mandatory, so \ (n-1 \) sides can be converted into the remaining \ (n-1 \) weights points (each point to the edge weights of its parent). So the right side and became the largest maximum points and right.
Happily then be transferred: Let nodes \ (X \) left sons \ (L_x \) , the right son is \ (r_x \) , then \ (f_ {x, i} = \ max_ \ limits { J \ in [0,. 1-I]} \ {{L_x F_, F_ {+} J r_x,. 1-I-J} \} + val_x \) .
As \ (l_x \) and \ (r_x \)The method for finding, see below \ (trick \) it.
trick
A given \ (n-1 \) Article undirected edge \ (n (n \ leqslant 3 \ times 10 ^ 3) \) point binary tree root method for finding left and right child nodes:
establishing an adjacency matrix, but this to save as \ (int \) form, \ (G_ {X, Y} \) stored is \ ((x, y) \ ) of the right side.
Started to build from the root, recursively from top down.
The current node to each recursion \ (X \) are traversed when the \ (n-\) nodes, a first node has to find the right side of it as \ (L_x \) , then the recursive processing node. Directly after exiting the loop can be returned. Looking for \ (r_x \) Note To re-iterate \ (n \) nodes, find a node has a first right side of it as \ (r_x \) , then recursively processing the node.
detail
Note two boundaries: \ (F_ {X, 0} \) represents a group selected \ (0 \) node, the answer is bound \ (0 \) ; \ (L_x = 0 \) and \ (r_x = 0 \) ( that \ (x \) can not be selected sub-tree leaf nodes), the direct return to itself the right value.
Code
\(View\) \(Code\)
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int ret=0,f=1;
char ch=getchar();
while('9'<ch||ch<'0')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9')
{
ret=(ret<<1)+(ret<<3)+ch-'0';
ch=getchar();
}
return ret*f;
}
int n,q,x,y,w,g[105][105],val[105],l[105],r[105],f[105][105];
void make_tree(int x)
{
for(register int i=1;i<=n;i++)
{
if(g[x][i]||!g[x][i])
{
val[i]=g[x][i];
g[x][i]=-1;
g[i][x]=-1;
l[x]=i;
make_tree(i);
break;
}
}
for(register int i=1;i<=n;i++)
{
if(g[x][i]||!g[x][i])
{
val[i]=g[x][i];
g[x][i]=-1;
g[i][x]=-1;
r[x]=i;
make_tree(i);
break;
}
}
}
int dp(int x,int cnt)
{
if(!cnt)
return 0;
if((!l[x])&&(!r[x]))
return val[x];
if(f[x][cnt])
return f[x][cnt];
for(register int i=0;i<cnt;i++)
{
f[x][cnt]=max(f[x][cnt],dp(l[x],i)+dp(r[x],cnt-1-i)+val[x]);
}
return f[x][cnt];
}
int main()
{
n=read();
q=read();
memset(g,-1,sizeof(g));
for(register int i=1;i<n;i++)
{
x=read();
y=read();
w=read();
g[x][y]=w;
g[y][x]=w;
}
make_tree(1);
printf("%d\n",dp(1,q+1));
return 0;
}