坑点:可能我英语不太好没看出来,假如一个点bugs为0,也至少需要有一个人通过他(不用停留在上面,也就是在后面可以再使用),所以只需要在bugs为0可以直接获得brain的基础上,把所有的dp[u][0]都初始化为0就可以了。
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e2+5;
int n,m;
int bugs[N], p[N];
int dp[N][N];
int t[N];
vector<int> G[N];
void init() {
for(int i=1; i<=n; ++i) {
G[i].clear();
}
}
void AddEdge(int a, int b) {
G[a].push_back(b);
G[b].push_back(a);
}
void solve(int u, int fa) {
for(int i=0; i<G[u].size(); ++i) {
int v=G[u][i];
if(v!=fa) {
solve(v, u);
}
}
memset(t, 0, sizeof(t));
for(int i=0; i<G[u].size(); ++i) {
int v=G[u][i];
if(v==fa) continue;
for(int j=m; j>=0; --j) {
for(int k=0; k<=j; ++k)
{
t[j]=max(t[j], t[j-k]+dp[v][k]);
}
}
}
for(int i=1; i<=m; ++i) {
int r=bugs[u]?i-(bugs[u]-1)/20-1:i;
if(r<0)
{
dp[u][i]=0;
continue;
}
dp[u][i]=p[u]+t[r];
}
}
int main() {
while(~scanf("%d%d", &n, &m)) {
if(n==-1&&m==-1) break;
init();
for(int i=1; i<=n; ++i) {
scanf("%d%d", bugs+i, p+i);
}
for(int i=1; i<n; ++i) {
int a, b;
scanf("%d%d", &a, &b);
AddEdge(a, b);
}
solve(1, 0);
printf("%d\n", dp[1][m]);
}
return 0;
}