2018.07.07【2018提高组】模拟B组
【GDOI2005】寻宝之旅【难】 (Standard IO)
题目:
探险队长凯因意外的弄到了一份黑暗森林的藏宝图,于是,探险队一行人便踏上了寻宝之旅,去寻找传说中的宝藏。
藏宝点分布在黑暗森林的各处,每个点有一个值,表示藏宝的价值。它们之间由一些小路相连,小路不会形成环,即两个宝藏点之间有且只有一条通路。探险队从其中的一点出发,每次他们可以留一个人在此点开采宝藏,也可以不留,然后其余的人可以分成若干队向这一点相邻的点走去。需要注意的是,如果他们把队伍分成两队或两队以上,就必须留一个人在当前点,提供联络和通讯,当然这个人也可以一边开采此地的宝藏。并且,为了节约时间,队伍在前往开采宝藏的过程中是不会走回头路的。现在你作为队长的助理,已经提供了这幅藏宝图,请你算出探险队所能开采的最大宝藏的价值。
数据:
Input
第一行有两个正整数n(1<=n<=100),表示藏宝点的个数,m(1<=m=100)表示探险队的人数。
第二行是n个不超过100的正整数,分别表示1到n每个点的宝藏价值。
接下来的n-1行,每行两个数,x和y(1<=x,y<=n,x<>y),表示藏宝点x,y之间有一条路,数据保证不会有重复的路出现。
假设一开始探险队在点1处。
Output
一个整数,表示探险队所能获得最大的宝藏价值。
Sample Input
5 3
1 3 7 2 8
1 2
2 3
1 4
4 5
Sample Output
16
思路:树形dp
https://blog.csdn.net/gx_man_vip/article/details/80952076
var
f,g:array[0..105,0..105] of longint;
tt:array[0..1005,1..2] of longint;
cp,rp,ls,a:array[0..105] of longint;
i,j,n,m,k,x,y:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
procedure dfs(x,d:longint);
var
i,j,y,k:longint;
begin
f[x,1]:=a[x];
i:=ls[x];
while i>0 do
begin
if tt[i,1]<>d then
begin
y:=tt[i,1];
dfs(y,x);
for j:=1 to m do
begin
cp[j]:=max(f[y,j],f[x,j]);
rp[j]:=max(f[y,j],g[x,j]);
end;
for j:=1 to m do
for k:=0 to j-1 do
begin
cp[j]:=max(cp[j],g[x,j-k-1]+f[y,k]+a[x]);
rp[j]:=max(rp[j],g[x,j-k]+f[y,k]);
end;
for j:=1 to m do
begin
f[x,j]:=cp[j];
g[x,j]:=rp[j];
end;
end;
i:=tt[i,2];
end;
end;
begin
readln(n,m);
for i:=1 to n do
read(a[i]);
for i:=1 to n-1 do
begin
readln(x,y);
inc(j);
tt[j,1]:=y; tt[j,2]:=ls[x]; ls[x]:=j;
inc(j);
tt[j,1]:=x; tt[j,2]:=ls[y]; ls[y]:=j;
end;
dfs(1,0);
writeln(f[1,m]);
end.