题意:求一个树上背包~~
先贴代码存一下,好像打挂了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 400;
const int INF = 0x3c;
int dp[maxn][maxn][3];
inline int read() {
int q=0,f=1;char ch = getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;ch=getchar();
}
while(isdigit(ch)){
q=q*10+ch-'0';ch=getchar();
}
return q*f;
}
int cnt;
int head[maxn << 1];
int n,m,t;
struct edge {
int to;
int nxt;
int w;
}e[maxn << 1];
int ans;
inline void Add_edge(int u,int v,int w) {
e[++cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
e[cnt].w = w;
e[++cnt].to = u;
e[cnt].nxt = head[v];
head[v] = cnt;
e[cnt].w = w;
}
int s[maxn];
int cost[maxn];
inline void dfs(int x,int fa) {
for(int i = 0;i <= t; ++i) {
if(i < s[x]) {
dp[x][i][0] = dp[x][i][1] = dp[x][i][2] = -INF;
}
else {
dp[x][i][0] = dp[x][i][1] = dp[x][i][2] = cost[x];
}
}
for(int i = head[x];i;i=e[i].nxt) {
int y = e[i].to;
if(y != fa) {
dfs(y,x);
for(int j = t;j >= e[i].w; --j) {
for(int k = 0;k <= j - e[i].w; ++k) {
if(j - k >= 2 * e[i].w) {
dp[x][j][2] = max(dp[x][j][2],dp[y][k][0] + dp[x][j - 2 * e[i].w - k][2]);
}
if(j - k >= 2 * e[i].w) dp[x][j][2] = max(dp[x][j][2],dp[y][k][2] + dp[x][j - k - 2 * e[i].w][0]);
dp[x][j][2] = max(dp[x][j][2],dp[y][k][1] + dp[x][j - k - e[i].w][1]);
if(j - k >= 2 * e[i].w) {
dp[x][j][1] = max(dp[x][j][1],dp[y][k][0] + dp[x][j - k - 2 * e[i].w][1]);
}
dp[x][j][1] = max(dp[x][j][1],dp[y][k][1] + dp[x][j - k - e[i].w][0]);
if(j - k >= 2 * e[i].w) {
dp[x][j][0] = max(dp[x][j][0],dp[y][k][0] + dp[x][j - k - 2 * e[i].w][0]);
}
}
}
}
}
}
int main () {
freopen("toyuq.in","r",stdin);
freopen("toyuq.out","w",stdout);
n = read(),t = read();
for(int i = 1;i <= n; ++i) {
cost[i] = read();
}
for(int i = 1;i <= n; ++i) {
s[i] = read();
}
for(int i = 1;i < n; ++i) {
int x = read(),y = read(),z = read();
Add_edge(x,y,z);
}
dfs(1,0);
for(int i = 1;i <= n; ++i) {
ans = max(ans,dp[i][t][2]);
}
printf("%d\n",ans);
return 0;
}