HDU 4003 Find Metal Mineral(樹形揹包DP)
阿新 • • 發佈:2018-11-08
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; const int N = 10100; struct Node { int to; int cap; }; vector<Node> v[N]; int dp[N][12], vis[N]; //dp[i][j] 用 j 個機器人去採以 i 為根節點的子樹的所有礦石的最小花費 int n, s, k; void dfs(int father) { vis[father] = 1; for(int i = 0; i < v[father].size(); i++) { Node child = v[father][i]; if(vis[child.to] == 1) continue; dfs(child.to); for(int num = k; num >= 0; num--) { //注意0 dp[father][num] += dp[child.to][0] + 2*child.cap;//最大結果,派下去又返回father for(int j = 1; j <= num; j++) dp[father][num] = min(dp[father][num], dp[father][num-j] + dp[child.to][j] + j*child.cap); //派j個機器人給v子樹就會經過father-child之間的邊j次 } } } int main() { freopen("data.in", "r", stdin); while(~scanf("%d%d%d", &n, &s, &k)) { for(int i = 0; i < n-1; i++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); Node tmp; tmp.to = y; tmp.cap = z; v[x].push_back(tmp);\ tmp.to = x; v[y].push_back(tmp); } memset(vis, 0, sizeof(vis)); memset(dp, 0, sizeof(dp)); dfs(s); printf("%d\n",dp[s][k]); for(int i=1; i<=n; i++) v[i].clear(); } return 0; }