也可以叫做树形背包 因为在回溯的时候像01背包一样 枚举每个物品 从最大容量开始更新
这里的物品代表以i为根的子树
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int maxn = 110; struct node { int e; int w; }; int dp[maxn][maxn*2]; vector <node> a[maxn]; int b[maxn]; bool vis[maxn]; int n, s, m; void dfs(int u, int t) { //if(vis[u][t]) // return dp[u][t]; if(t < 0) return; for(int i = 0; i <= t; i++) dp[u][i] = b[u]; vis[u] = true; for(int i = 0; i < a[u].size(); i++) { node v = a[u][i]; if(vis[v.e]) continue; dfs(v.e, t-2*v.w); for(int j = t; j >= 2*v.w; j--) { for(int k = 0; k <= j-2*v.w; k++) { node vv = a[v.e][i]; dp[u][j] = max(dp[u][j], dp[u][j-k-2*v.w] + dp[v.e][k]); } } } } int main() { while(scanf("%d", &n) == 1) { for(int i = 1; i <= n; i++) { scanf("%d", &b[i]); a[i].clear(); } for(int i = 1; i < n; i++) { int u, v, w; scanf("%d %d %d", &u, &v, &w); a[u].push_back((node){v, w}); a[v].push_back((node){u, w}); } scanf("%d %d", &s, &m); memset(dp, 0, sizeof(dp)); memset(vis, false, sizeof(vis)); dfs(s, m); printf("%d\n", dp[s][m]); } return 0; }
ZOJ 3626 Treasure Hunt I / 树形DP
原文:http://blog.csdn.net/u011686226/article/details/19421407