第一道树形DP。很容易理解。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXN 105 6 7 typedef struct { 8 int n, p; 9 } room_t; 10 11 room_t rooms[MAXN]; 12 int adj[MAXN][MAXN]; 13 int dp[MAXN][MAXN]; 14 bool visit[MAXN]; 15 int n, m; 16 17 int max(int a, int b) { 18 return a>b ? a:b; 19 } 20 21 void dfs(int r) { 22 int i, j, k, num, v; 23 24 visit[r] = true; 25 num = (rooms[r].n+19) / 20; 26 for (i=num; i<=m; ++i) 27 dp[r][i] = rooms[r].p; 28 29 for (i=1; i<=adj[r][0]; ++i) { 30 v = adj[r][i]; 31 if (visit[v]) 32 continue; 33 dfs(v); 34 for (j=m; j>=num; --j) { 35 for (k=1; k+j<=m; ++k) { 36 if (dp[v][k]) { 37 dp[r][j+k] = max(dp[r][j+k], dp[r][j]+dp[v][k]); 38 } 39 } 40 } 41 } 42 } 43 44 int main() { 45 int i, j, k; 46 47 #ifndef ONLINE_JUDGE 48 freopen("data.in", "r", stdin); 49 #endif 50 51 while (scanf("%d %d", &n, &m) != EOF) { 52 if (n==-1 && m==-1) 53 break; 54 memset(adj, 0, sizeof(adj)); 55 memset(visit, false, sizeof(visit)); 56 memset(dp, 0, sizeof(dp)); 57 for (i=1; i<=n; ++i) { 58 scanf("%d %d", &rooms[i].n, &rooms[i].p); 59 } 60 for (i=1; i<n; ++i) { 61 scanf("%d %d", &j, &k); 62 ++adj[j][0]; 63 ++adj[k][0]; 64 adj[j][adj[j][0]] = k; 65 adj[k][adj[k][0]] = j; 66 } 67 if (m == 0) { 68 printf("0 "); 69 continue; 70 } 71 dfs(1); 72 printf("%d ", dp[1][m]); 73 } 74 75 return 0; 76 }