标签:
又是一道树上做分组背包的题目...
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = 999999999; 7 const int N = 2001; 8 int value[N]; 9 int head[N]; 10 int dp[N][N]; 11 int cnt[N]; 12 int ans[N]; 13 int n, e; 14 15 struct Edge 16 { 17 int v, next; 18 } edge[N * 2]; 19 20 void addEdge( int u, int v ) 21 { 22 edge[e].v = v; 23 edge[e].next = head[u]; 24 head[u] = e++; 25 } 26 27 void dfs( int u, int fa ) 28 { 29 dp[u][1] = value[u]; 30 cnt[u] = 1; 31 for ( int i = head[u]; i != -1; i = edge[i].next ) 32 { 33 int v = edge[i].v; 34 if ( v == fa ) continue; 35 dfs( v, u ); 36 cnt[u] += cnt[v]; 37 } 38 for ( int i = head[u]; i != -1; i = edge[i].next ) 39 { 40 int v = edge[i].v; 41 if ( v == fa ) continue; 42 for ( int j = cnt[u]; j > 1; j-- ) 43 { 44 for ( int k = 1; k <= cnt[v] && k < j; k++ ) 45 { 46 dp[u][j] = min( dp[u][j], dp[u][j - k] + dp[v][k] ); 47 } 48 } 49 } 50 } 51 52 int main () 53 { 54 while ( scanf("%d", &n) != EOF ) 55 { 56 e = 0; 57 memset( head, -1, sizeof(head) ); 58 for ( int i = 1; i <= n; i++ ) 59 { 60 scanf("%d", value + i); 61 } 62 for ( int i = 1; i < n; i++ ) 63 { 64 int u, v; 65 scanf("%d%d", &u, &v); 66 addEdge( u, v ); 67 addEdge( v, u ); 68 } 69 for ( int i = 1; i <= n; i++ ) 70 { 71 for ( int j = 1; j <= n; j++ ) 72 { 73 dp[i][j] = INF; 74 } 75 } 76 dfs( 1, -1 ); 77 for ( int i = 1; i <= n; i++ ) 78 { 79 ans[i] = INF; 80 for ( int j = 1; j <= n; j++ ) 81 { 82 ans[i] = min( ans[i], dp[j][i] ); 83 } 84 printf("%d", ans[i]); 85 if ( i != n ) putchar(‘ ‘); 86 else putchar(‘\n‘); 87 } 88 } 89 return 0; 90 }
标签:
原文地址:http://www.cnblogs.com/huoxiayu/p/4694619.html