http://poj.org/problem?id=2486 //树形DP #include<stdio.h> #include<string.h> #define M 101 int g[M][M], dp[M][2*M][2], num[M];//g用来存放图,dp[i][k][j]表示从i开始走K步能吃到的最大苹果树,j=0表示要返回到i,j=1表示不要返回 int app[M]; bool v[M]; int N, K; inline int max(int a, int b) { return a>b?a:b; } void dfs(int x) { int i, y; v[x] = true; for(i=0; i<num[x]; i++) { y = g[x][i]; if(!v[y]) { dfs(y); for(int k=K; k>=0; k--) for(int j=0; j<K; j++) { if(k >= 2+j) { dp[x][k][0] = max(dp[x][k][0], dp[x][j][0] + dp[y][k-2-j][0]); dp[x][k][1] = max(dp[x][k][1], dp[x][j][1] + dp[y][k-2-j][0]); } if(k >= 1+j) { dp[x][k][1] = max(dp[x][k][1], dp[x][j][0] + dp[y][k-1-j][1]); } } } } } int main() { // freopen("in.txt","r",stdin); int i, j; while(scanf("%d %d", &N, &K) != EOF) { if(N == 0 && K == 0) break; memset(num, 0, sizeof(num)); memset(v, false, sizeof(v)); int a, b; for(i=1; i<=N; i++) scanf("%d", &app[i]); for(i=0; i<N-1; i++) { scanf("%d %d", &a, &b); g[a][num[a]++] = b; g[b][num[b]++] = a; } for(i=1; i<=N; i++) for(j=0; j<=K; j++) { dp[i][j][0] = dp[i][j][1] = app[i]; } dfs(1); printf("%d/n",dp[1][K][1]); } return 0; }