题意:
就是一个房间有a个虫子,有b个“大脑”(百度翻译的,将就看吧。。。)你把虫子杀了就可以获得b个大脑。一个士兵能杀死20个虫子。
思路:
猛的一看,这不就是背包吗?但是好像又是树有关系。那就建树啊,在树上dp一下就行了!
建树按照这个建树,感觉比较方便。
struct node{
int v,next;
}edge[10010];
int head[110],cur;
void add(int s,int t){
edge[cur].v=t;
edge[cur].next=head[s];
head[s]=cur++;
}
建好树之后背包一遍就可以了。
#include<bits/stdc++.h>
using namespace std;
struct node{
int v,next;
}edge[10010];
int head[110],cur;
int dp[110][110];
int n,m,a,b;
void add(int s,int t){
edge[cur].v=t;
edge[cur].next=head[s];
head[s]=cur++;
}
int num[110],v[110];
void dfs(int son,int father){
int tmp=(num[son]+19)/20;
for(int i=head[son];~i;i=edge[i].next){
int to=edge[i].v;
if(to==father)continue;
dfs(to,son);
for(int j=m;j>=tmp;j--){
for(int k=1;j-k>=tmp&&k<=m;k++){
dp[son][j]=max(dp[son][j],dp[son][j-k]+dp[to][k]);
}
}
}
for(int i=tmp;i<=m;i++)dp[son][i]+=v[son];
}
int main(){
while(~scanf("%d%d",&n,&m)&&(~n||~m)){
memset(head,-1,sizeof head),memset(dp,0,sizeof dp),cur=0;
for(int i=1;i<=n;i++)scanf("%d%d",&num[i],&v[i]);
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
if(m==0){puts("0");continue;}
dfs(1,0);
printf("%d\n",dp[1][m]);
}
return 0;
}