hdu 4003 Find Metal Mineral
来源:互联网 发布:matlab编程怎么入门 编辑:程序博客网 时间:2024/06/05 05:35
#include <cstdio>#include <cstring>int n, s, k;const int MAXN = 10010;struct EDGE{ int v, next, w;}edge[MAXN * 2];int head[MAXN];int cnt;int dp[MAXN][11];void addedge(int u, int v, int val){ edge[cnt].v = v; edge[cnt].next = head[u]; edge[cnt].w = val; head[u] = cnt++;}void dfs(int t, int fa){ //dp[i][j] 暂时在i的子树中最多用j个机器人达到的最优值(J个机器人回去I节点) for(int p = head[t]; p != -1; p = edge[p].next) { if(edge[p].v == fa) continue; dfs(edge[p].v, t); } if(head[t] == -1 || (edge[head[t]].next == -1 && fa != -1)) //一颗空树或者叶子节点,返回 { for(int i = 0; i <= k; i++)//注意一下这个到底是否成立 { dp[t][i] = 0; } return; } for(int p = head[t]; p != -1; p = edge[p].next) { int v = edge[p].v; if(v == fa) continue;//!!!! for(int j = k; j >= 0; j--) { if(dp[t][j] == -1)//j个不返回 { if(j > 0) { dp[t][j] = dp[v][0] + 2 * edge[p].w; for(int i = 1; i <= j; i++) if(dp[t][j] > dp[v][i] + i * edge[p].w) { dp[t][j] = dp[v][i] + i * edge[p].w; } } else { dp[t][j] = dp[v][j] + 2 * edge[p].w; } continue; } else { dp[t][j] += dp[v][0] + 2 * edge[p].w; for(int i = 1; i <= j; i++) if(dp[t][j] > dp[t][j-i] + dp[v][i] + i * edge[p].w) { dp[t][j] = dp[t][j-i] + dp[v][i] + i * edge[p].w; } } } }}int main(){ while(scanf("%d%d%d", &n, &s, &k) != EOF) { cnt = 0; memset(head, -1, sizeof(head)); for(int i = 1; i < n; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); addedge(a, b, c); addedge(b, a, c); } memset(dp, -1, sizeof(dp)); dfs(s, -1); printf("%d\n", dp[s][k]); } return 0;}