Description
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
2 5
\ /
3 4
\ /
1
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
Input
第1行2个数,N和Q(1<=Q<= N,1<n<=100)。n表示树的结点数,q表示要保留的树枝数量。接下来n-1行描述树枝的信息。每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。每根树枝上的苹果不超过30000个。< font="">
Output
一个数,最多能留住的苹果的数量。
Sample Input
5 2
1 3 1
1 4 10
2 3 20
3 5 20
Sample Output
21
分析:f[I,j]表示i节点剪掉j的最大值,a[I,1]表示i的左节点,a[I,2]表示i的右节点,即
f[i,j]:=f[a[i,1],k]+f[a[i,2],j-k-1]+d[i]; (0<=k<=j-1)
标程:
· var
· f,b:array[0..200,0..200] of longint;
· a:array[0..200,1..2] of longint;
· d:array[0..200] of longint;
· i,j,k,l:longint;
· n,m:longint;
· ans:longint;
·
· procedure maketree(v:longint);
· var
· i,j,k:longint;
· begin
· for i:=1 to n do
· begin
· if b[v,i]>=0 then
· begin
· a[v,1]:=i;
· d[i]:=b[v,i];
· b[v,i]:=-1; b[i,v]:=-1;
· maketree(i);
· break;
· end;
· end;
· for i:=1 to n do
· begin
· if b[v,i]>=0 then
· begin
· a[v,2]:=i;
· d[i]:=b[v,i];
· b[v,i]:=-1; b[i,v]:=-1;
· maketree(i);
· break;
· end;
· end;
· end;
·
· procedure dfs(l,r:longint);
· var
· i,j,k:longint;
· begin
· if r=0 then exit;
· if f[l,r]<>0 then exit;
· if (a[l,1]=0) and (a[l,2]=0)
· then begin
· f[l,r]:=d[l];
· exit;
· end;
· for i:=0 to r-1 do
· begin
· dfs(a[l,1],i);
· dfs(a[l,2],r-i-1);
· if f[l,r]<f[a[l,1],i]+f[a[l,2],r-i-1]+d[l]
· then
· f[l,r]:=f[a[l,1],i]+f[a[l,2],r-i-1]+d[l];
· end;
· end;
·
· begin
· readln(n,m);
· m:=m+1;
· for i:=1 to n do
· for j:=1 to n do
· b[i,j]:=-maxlongint;
· for i:=1 to n-1 do
· begin
· readln(j,k,l);
· b[j,k]:=l;
· b[k,j]:=l;
· end;
· maketree(1);
· dfs(1,m);
· writeln(f[1,m]);
· end.