Galo
Description
给出一棵以
1
号点为根的
如果摘下了
i
号果子,那么
最多能摘
Data Constraint
n
*
wi
<=
105
Solution
经典例题,其实也没什么好讲的,就是树型依赖动态规划。
s
[
转移方程式如下
不会树型依赖动态规划请点这里
树型依赖动态规划
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,j,l) for(int i=j;i<=l;i++)
#define fd(i,j,l) for(int i=j;i>=l;i--)
using namespace std;
typedef long long ll;
const long long N=2e7+2e3,M=N/2;
ll f[N];
int ne[M],lb[M],la[M],s[M],d[M],w[M];
int n,m,j,k,l,i,o,a,b;
void llb(int a,int b)
{ne[++o]=la[a]; la[a]=o; lb[o]=b;}
int de(int a,int b)
{return (a-1)*(k+1)+b+1;}
ll max(ll a,ll b)
{if(a>b)return a;else return b;}
int main()
{
freopen("galo.in","r",stdin);
freopen("galo.out","w",stdout);
cin>>n>>k; int kk=k+1;
fo(i,2,n){
scanf("%d%d",&a,&b);
llb(a,i); w[i]=b;
}
int r,t;
d[k=1]=1;
s[1]=1;
s[0]=0;
for(f[1]=r=1;r;){
t=f[r];
s[t]+=s[f[r+1]];
if(la[t]){
f[++r]=lb[la[t]]; d[++k]=f[r];
la[t]=ne[la[t]]; s[f[r]]=1; f[r+1]=0;
}else r--;
}
w[1]=0;
fo(i,1,n)f[de(i,0)]=0;
k=kk;
fd(i,n,1)
fo(l,1,k)
f[de(i,l)]=
max(max(f[de(i+1,l)],f[de(i+s[d[i]],l)]),f[de(i+s[d[i]],l-1)]+w[d[i]]);
ll ans=0;
fo(i,1,k)ans=max(ans,f[de(1,i)]);
printf("%lld",ans);
}