一直想把他当树dp做 。。 怎么也想不出来转移方程 。。 后来灵机一动 。。 很像背包啊 。。 于是今天到机房就把他敲了 。。好久好久好久没做背包了 。。虽然某种说法上背包也是dp 。。
const int K = 209;
const int N = 109;
int dp[2][N][K];//0表示不回来;1表示回来
int val[N];
int vis[N];
int n, k;
vector<int>v[N];
void dfs(int u)
{
//cout<<u<<endl;
for(int i=0; i<=k; i++)
dp[0][u][i] = dp[1][u][i] = val[u];
vis[u] = 1;
for(int i=0; i<v[u].size(); i++)
{
//cout<<" +++ "<<endl;
int uu = v[u][i];
if(vis[uu]) continue;
dfs(uu);
for(int j=k; j>=0; j--)
for(int jj=0; jj<=j; jj++)
{
dp[0][u][j+2] = max( dp[0][u][j+2], dp[1][uu][jj] + dp[0][u][j-jj] );
dp[0][u][j+1] = max( dp[0][u][j+1], dp[0][uu][jj] + dp[1][u][j-jj] );
dp[1][u][j+2] = max( dp[1][u][j+2], dp[1][uu][jj] + dp[1][u][j-jj] );
}
}
}
int main()
{
while(~scanf("%d%d", &n, &k))
{
for(int i=1; i<=n; i++) scanf("%d", &val[i]);
for(int i=1; i<=n; i++) v[i].clear();
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
for(int i=1; i<n; i++)
{
int x, y;
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1);
printf("%d\n", dp[0][1][k]);
}
return 0;
}