Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of apples. Wshxzt starts her happy trip at one node. She can eat up all the apples in the nodes she reaches. HX is a kind guy. He knows that eating too many can make the lovely girl become fat. So he doesn’t allow Wshxzt to go more than K steps in the tree. It costs one step when she goes from one node to another adjacent node. Wshxzt likes apple very much. So she wants to eat as many as she can. Can you tell how many apples she can eat in at most K steps.
Input
There are several test cases in the input
Each test case contains three parts.
The first part is two numbers N K, whose meanings we have talked about just now. We denote the nodes by 1 2 ... N. Since it is a tree, each node can reach any other in only one route. (1<=N<=100, 0<=K<=200)
The second part contains N integers (All integers are nonnegative and not bigger than 1000). The ith number is the amount of apples in Node i.
The third part contains N-1 line. There are two numbers A,B in each line, meaning that Node A and Node B are adjacent.
Input will be ended by the end of file.
Note: Wshxzt starts at Node 1.
Output
For each test case, output the maximal numbers of apples Wshxzt can eat at a line.
Sample Input
2 1
0 11
1 2
3 2
0 1 2
1 2
1 3
Sample Output
11
2
题意:给你一颗树,每个节点有一个权值,现在你随便找一个点,走k步,求能获得的最大权值和,可以走重复的节点,但是节点的权值不能重复加,
题解:dp[i][j][true] 表示在i节点,已经走了j步,true表示回到i节点(反之不会到i节点),获得的最大权值和,转移方程看代码。
//计算以u节点为根的最大权值和
for(int j=k; j>=1; j--) {
for(int t=1; t<=j; t++) {
dp[u][j][1] = max(dp[u][j][1], dp[u][j-t][1] + dp[v][t-2][1]);
//回到u节点,u为根其他节点走了j-t步,回到u节点,然后走到v节点,以v节点为根走了t-2步,回到v节点(其中有两步是u-v的来回)
dp[u][j][0] = max(dp[u][j][0], dp[u][j-t][1] + dp[v][t-1][0]);
//不会到u节点,u为根其他节点走了j-t步,回到u节点,然后走到v节点,以v节点为根走了t-1步,不需要回到v节点(其中有一步是u->v)
dp[u][j][0] = max(dp[u][j][0], dp[u][j-t][0] + dp[v][t-2][1]);
//不会到u节点,先从u走向v,然后以v为根走了t-2步,回到v节点,再回到u节点,然后在其他点走了j-t步,不需要回到u节点(其中有两步是u-v的来回)
}
}
//#include"bits/stdc++.h"
//#include<unordered_map>
//#include<unordered_set>
#include<iostream>
#include<sstream>
#include<iterator>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<vector>
#include<bitset>
#include<climits>
#include<queue>
#include<iomanip>
#include<cmath>
#include<stack>
#include<map>
#include<ctime>
#include<new>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define MT(a,b) memset(a,b,sizeof(a))
#define lson l, mid, node << 1
#define rson mid + 1, r, node << 1 | 1
const int INF = 0x3f3f3f3f;
const int O = 1e6;
const int mod = 10007;
const int maxn = 2e2+5;
const double PI = acos(-1.0);
const double E = 2.718281828459;
const int _ = 1;
const int __ = 2;
const int ___ = 3;
struct dd{
int to, next;
}e[maxn<<1];
int cnt = 0, head[maxn];
void add(int u, int v){
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt ++;
}
int dp[maxn][maxn][2];
int a[maxn];
int n, k;
void dfs(int u, int fa){
for(int i=0; i<=k; i++) dp[u][i][0] = dp[u][i][1] = a[u];
for(int i=head[u]; i!=-1; i=e[i].next) {
int v = e[i].to; if(v == fa) continue;
dfs(v, u);
for(int j=k; j>=1; j--) {
for(int t=1; t<=j; t++) {
if(t >= 2) dp[u][j][1] = max(dp[u][j][1], dp[u][j-t][1] + dp[v][t-2][1]);
dp[u][j][0] = max(dp[u][j][0], dp[u][j-t][1] + dp[v][t-1][0]);
if(t >= 2) dp[u][j][0] = max(dp[u][j][0], dp[u][j-t][0] + dp[v][t-2][1]);
}
}
}
}
int main(){
while(~ scanf("%d%d", &n, &k)){
cnt = 0; MT(head, -1);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
for(int i=1; i<n; i++) {
int u, v; scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
dfs(1, -1);
int ans = max(dp[1][k][0], dp[1][k][1]);
printf("%d\n", ans);
}
return 0;
}