很显然是树形背包,注意m为0的情况。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 101; 7 int head[N]; 8 int bn[N]; 9 int value[N]; 10 int dp[N][N]; 11 int n, m, e; 12 13 struct Edge 14 { 15 int v, next; 16 } edge[N << 1]; 17 18 void addEdge( int u, int v ) 19 { 20 edge[e].v = v; 21 edge[e].next = head[u]; 22 head[u] = e++; 23 } 24 25 void dfs( int u, int fa ) 26 { 27 int tmp = ( bn[u] + 19 ) / 20; 28 for ( int i = tmp; i <= m; i++ ) dp[u][i] = value[u]; 29 for ( int i = head[u]; i != -1; i = edge[i].next ) 30 { 31 int v = edge[i].v; 32 if ( v == fa ) continue; 33 dfs( v, u ); 34 for ( int j = m; j >= tmp; j-- ) 35 { 36 for ( int k = 1; j - k >= tmp; k++ ) 37 { 38 dp[u][j] = max( dp[u][j], dp[u][j - k] + dp[v][k] ); 39 } 40 } 41 } 42 } 43 44 int main () 45 { 46 while ( scanf("%d%d", &n, &m) != EOF ) 47 { 48 if ( n == -1 && m == -1 ) break; 49 for ( int i = 1; i <= n; i++ ) 50 { 51 scanf("%d%d", bn + i, value + i); 52 } 53 e = 0; 54 memset( head, -1, sizeof(head) ); 55 for ( int i = 1; i < n; i++ ) 56 { 57 int u, v; 58 scanf("%d%d", &u, &v); 59 addEdge( u, v ); 60 addEdge( v, u ); 61 } 62 if ( !m ) 63 { 64 puts("0"); 65 continue; 66 } 67 memset( dp, 0, sizeof(dp) ); 68 dfs( 1, -1 ); 69 printf("%d ", dp[1][m]); 70 } 71 return 0; 72 }