假期回家就一直是各种玩,看了4部连续剧以及记不清几部电影了,聚会打牌也不会缺席,所以懈怠了一个多月之后,今天刚刚看完三国演义,突然想看看书,没什么心情看代码,只好刷题目找状态啦,本来已经睡了的,想来想去辗转反侧各种睡不着,又起来思路敲好,卡了将近一个小时总算过了,所以从现在开始重新回归ACM,废话不多说了,看题。。。
这题就是坑爹的货,没考虑m=0的情况,卡了一个小时;
数据比较小,不过为了熟练刚学的前向星,用前向星建的图;
采用动态数组dfs就ok了,只要注意m=0时的brain。
ACcode:
#include<stdio.h>
#include<iostream>
using namespace std;
const int nsize=110;
int n,m;
int dp[nsize],temp[nsize];
int w[nsize],bug[nsize],vis[nsize];
int e[nsize<<1],next[nsize<<1],head[nsize];
void add(int u,int v,int j)
{
e[j]=v;
next[j]=head[u];
head[u]=j;
}
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
int Min(int a1,int a2)
{
return a1<a2?a1:a2;
}
void dfs(int rt)
{
vis[rt]=1;
int num=int((bug[rt]+19)/20);
if (num>m)
{
for (int i=0;i<=m;i++) temp[i]=0;
return ;
}
int cnt[nsize]={0};
for (int i=head[rt];i>=0;i=next[i])
{
if (vis[e[i]]!=1)
{
dfs(e[i]);
for (int j=m;j>=0;j--)
{
for (int k=0;k<j;k++)
cnt[j]=Max(cnt[j],cnt[k]+temp[j-k]);
}
}
}
for (int i=0;i<num;i++) temp[i]=0;
for (int i=num;i<=m;i++) temp[i]=cnt[i-num]+w[rt];
}
int main()
{
int u,v;
while (scanf("%d%d",&n,&m))
{
if (n==-1&&m==-1) break;
for (int i=1;i<=n;i++)
{
scanf("%d%d",&bug[i],&w[i]);
vis[i]=-1;
}
for (int i=0;i<=n;i++) head[i]=-1;
for (int i=0;i<=m+m;i++) dp[i]=0;
for (int i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
add(u,v,i+i-1);
add(v,u,i+i);
}
dfs(1);
if (m==0) temp[0]=0;
printf("%d\n",temp[m]);
}
return 0;
}