此题很好,很费脑力,还好以前把背包9讲看完了,这次容易理解点
#include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <queue> using namespace std; #define max(a,b) (((a) > (b)) ? (a) : (b)) const int INF = 1e9; struct Node { int y, w; Node(int _y, int _w) : y(_y), w(_w) { } }; vector<Node> map[110]; int dp[110][510]; // dp[i][j] 从i出发又返回i,最大花费为j时所取得的价值 int val[110], mark[110]; int bfs(int s, int e) { int dist[110], f[110]; for (int i = 0; i < 110; ++i) dist[i] = INF; f[s] = -1; dist[s] = 0; queue<int> q; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < map[u].size(); ++i) { Node &v = map[u][i]; if (dist[v.y] > dist[u] + v.w) { f[v.y] = u; dist[v.y] = dist[u] + v.w; q.push(v.y); } } } for (int i = e; i != -1; i = f[i]) mark[i] = 1; return dist[e]; } void dfs(int u, int pre, int mval) { dp[u][0] = val[u]; for (int i = 0; i < map[u].size(); ++i) { int y = map[u][i].y; int w = map[u][i].w; if (y == pre || mark[y]) continue; dfs(y, u, mval); for (int j = mval; j >= 0; --j) for (int k = 0; k <= j-2*w; ++k) if (dp[u][j-k-2*w] != -1 && dp[y][k] != -1) dp[u][j] = max(dp[u][j], dp[y][k] + dp[u][j-k-2*w]); } } int main() { int n, t; while (scanf("%d %d", &n, &t) == 2) { memset(map, 0, sizeof(map)); memset(dp, -1, sizeof(dp)); memset(mark, 0, sizeof(mark)); int a, b, c; for (int i = 1; i < n; ++i) { scanf("%d %d %d", &a, &b, &c); map[a].push_back(Node(b, c)); map[b].push_back(Node(a, c)); } for (int i = 1; i <= n; ++i) scanf("%d", &val[i]); int tt = bfs(1, n); if (tt > t) { printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n"); continue; } for (int i = 1; i <= n; ++i) if (mark[i]) dfs(i, -1, t - tt); int dp2[510], tmax = t - tt; memset(dp2, -1, sizeof(dp2)); dp2[0] = 0; for (int i = 1; i <= n; ++i) { if (!mark[i]) continue; for (int j = tmax; j >= 0; --j) { for (int k = 0; k <= j; ++k) if (dp2[j-k] != -1 && dp[i][k] != -1) dp2[j] = max(dp2[j], dp2[j-k] + dp[i][k]); } } int ans = 0; for (int i = 0; i <= tmax; ++i) if (ans < dp2[i]) ans = dp2[i]; printf("%d\n", ans); } return 0; }