#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define max (a>b)?a:b const int nMax = 105; int map[nMax][nMax]; int d[nMax][nMax]; int visit[nMax]; struct Room { int bugs, brains; }room[nMax]; int N, M; void dp(int u)//这里的动态规划,等于分层处理,每次处理一层。递归非递归相互配合。 { visit[u] = 1; int r = (room[u].bugs + 19) / 20; for(int i = M; i >= r; i --) d[u][i] = room[u].brains;//初始化 for(int v = 1;v <= N; ++ v) { if(map[u][v] && !visit[v]) { dp(v); for(int j = M; j >= r; j --)//这里需要注意,从大到小,这样可以避免自身节点的干扰。这里的d只需要处理其他子树 { //这里如果想使用递归,则从M到r,执行对u的更新处理即可。 for(int k = 1; k <= j - r; k ++) d[u][j] = max(d[u][j], d[u][j - k] + d[v][k]); } } } } int main() { while(scanf("%d%d", &N, &M) != EOF) { if(N == -1) break; for(int i = 1; i <= N; ++ i) scanf("%d%d", &room[i].bugs, &room[i].brains); memset(map, 0, sizeof(map)); for(int i = 1; i < N; ++ i) { int a, b; scanf("%d%d", &a, &b); map[a][b] = map[b][a] = 1; } if(!M) //如果M为零,需要特殊判断,特殊数据 { printf("0\n"); continue; } memset(d, 0, sizeof(d)); memset(visit, 0, sizeof(visit)); dp(1); printf("%d\n", d[1][M]); } return 0; }
时间: 2024-10-11 21:23:35