#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;
}
HDU 4003 Find Metal Mineral(树形背包DP)
猜你喜欢
转载自blog.csdn.net/ccshijtgc/article/details/81219118
今日推荐
周排行