主要知识点就是树形dp
#include <iostream>
#include <vector>
using namespace std;
int n, m;
int brains[105];
int dp[105][105];
vector<int> adj[105];
int cost[105];
void dfs(int d, int f) {
for (int i = cost[d]; i <= m; i++)
dp[d][i] = brains[d];
int size = adj[d].size();
for (int i = 0; i < size; i++) {
int v = adj[d][i];
if (v == f)
continue;
else
dfs(v, d);
for (int p = m; p >= cost[d]; p--)
{
for (int k = 1; k <= p - cost[d]; k++)
{
if (dp[d][p] < dp[d][p - k] + dp[v][k])
{
dp[d][p] = dp[d][p - k] + dp[v][k];
}
}
}
}
}
int main()
{
int x, y;
do {
cin >> n >> m;
int bug;
for (int i = 0; i < 105; i++)
{
adj[i].clear();
}
if (n == -1 && m == -1)
break;
for (int i = 0; i < n; i++)
{
cin >> bug >> brains[i];
cost[i] = (bug + 19) / 20;
}
for (int i = 0; i < n - 1; i++)
{
cin >> x >> y;
adj[x - 1].push_back(y - 1);
adj[y - 1].push_back(x - 1);
}
if (m == 0) {
cout << "0" << endl;
continue;
}
memset(dp, 0, sizeof(dp));
dfs(0, -1);
cout << dp[0][m] << endl;
} while (1);
return 0;
}