描述
curimit知道陶陶很喜欢吃苹果。于是curimit准备在陶陶生日的时候送给他一棵苹果树。
curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果,这棵树高度为h。
可是,当curimit把这棵树给陶陶看的时候,陶陶却说:“今年生日不收礼,收礼只收节点数减高度不超过k的苹果树。”这下curimit犯难了,curimit送来的树枝繁叶茂,不满足节点数-高度≤k。于是curimit决定剪掉一些枝条,使得修剪过后的树满足节点数-高度≤k,但是curimit又想保留尽量多的苹果数目。curimit想请你帮他算算经过修剪后的树最多能保留多少个苹果。
注:
一, 节点1为树根,不能把它剪掉。
二, 1个节点的树高度为1。
格式
输入格式
输入文件的第一行为两个整数n,k分别表示这棵树有n个节点,修剪后的树节点数-高度≤k。
第二行开始到第n+1行,每行有两个数,第i+1行的两个数father[i]和c[i]分别表示节点i的父亲是father[i]和节点i处有c[i]个苹果。
规定:节点1的父亲为0。
输出格式
输出文件仅包含一行,ans,表示在满足修建后的树节点数-高度≤k的条件下,最多能保留多少个苹果。
样例1
样例输入1[复制]
5 1
0 1
1 1
1 3
2 10
3 4
样例输出1[复制]
15
限制
全部1秒
提示
【约定】
对于10%的数据, n≤10
对于30%的数据, n≤100 0≤k≤20
对于100%的数据,n≤4000 0≤k≤=500
神啦,树形依赖背包还可以出成这样
我们回忆我们怎么做树形依赖背包的
s是i的儿子,f[s]的初值为f[i],dfs(s),然后f[i,v]:=min(f[i,v],f[i,v-1]+a[s])
这样的话我们发现叶子节点存的f其实就是处理了这条链左边的节点所得到的信息
仔细观察题目条件,我们发现这个是树形依赖背包,但是有一条链免费,所以我们dfs两次,一次从左往右,一次从右往左
然后我们枚举免费的链,只枚举根到叶子节点的(1.我们只能保证叶子节点有上面这个性质2.免费的链当然是越深越好啦),然后更新答案
orz出题人

1 const 2 maxn=4040; 3 maxk=550; 4 var 5 fl,fr:array[0..maxn,0..maxk]of longint; 6 v:array[0..maxn,0..maxn]of longint; 7 a,sum,f:array[0..maxn]of longint; 8 n,k,ans:longint; 9 10 function max(x,y:longint):longint; 11 begin 12 if x>y then exit(x); 13 exit(y); 14 end; 15 16 procedure dfsl(x:longint); 17 var 18 i,j:longint; 19 begin 20 sum[x]:=sum[f[x]]+a[x]; 21 for i:=1 to v[x,0] do 22 begin 23 for j:=0 to k do 24 fl[v[x,i],j]:=fl[x,j]; 25 dfsl(v[x,i]); 26 for j:=1 to k do 27 fl[x,j]:=max(fl[x,j],fl[v[x,i],j-1]+a[v[x,i]]); 28 end; 29 end; 30 31 procedure dfsr(x:longint); 32 var 33 i,j:longint; 34 begin 35 for i:=v[x,0] downto 1 do 36 begin 37 for j:=0 to k do 38 fr[v[x,i],j]:=fr[x,j]; 39 dfsr(v[x,i]); 40 for j:=1 to k do 41 fr[x,j]:=max(fr[x,j],fr[v[x,i],j-1]+a[v[x,i]]); 42 end; 43 end; 44 45 procedure main; 46 var 47 i,x:longint; 48 begin 49 read(n,k); 50 for i:=1 to n do 51 begin 52 read(f[i],a[i]); 53 inc(v[f[i],0]);v[f[i],v[f[i],0]]:=i; 54 end; 55 dfsl(1); 56 dfsr(1); 57 for i:=1 to n do 58 if v[i,0]=0 then 59 for x:=0 to k do 60 ans:=max(ans,fl[i,x]+fr[i,k-x]+sum[i]); 61 writeln(ans); 62 end; 63 64 begin 65 main; 66 end.