hdu 4003(树形dp)

题意:一棵带权树,有K个机器人从原点S出发,问最小花费多少才能遍历所有结点。

思路:树形DP题,一开始想到的状态是三维的,仔细思考一下发现会超时,后来参考了网上的解题报告,发现了回来的机器人最多只要一个(如果有多个的话必定可以证明花费多于一个的)这样用dp[i][0]表示有一个机器人回来的情况,1-k表示用k个机器人遍历以i为根的子树的最小花费。

代码如下:

 1 /**************************************************
 2  * Author     : xiaohao Z
 3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
 4  * Last modified : 2014-04-03 18:10
 5  * Filename     : hdu_4003.cpp
 6  * Description     : 
 7  * ************************************************/
 8 
 9 #include <iostream>
10 #include <cstdio>
11 #include <cstring>
12 #include <cstdlib>
13 #include <cmath>
14 #include <algorithm>
15 #include <queue>
16 #include <stack>
17 #include <vector>
18 #include <set>
19 #include <map>
20 #define MP(a, b) make_pair(a, b)
21 #define PB(a) push_back(a)
22 
23 using namespace std;
24 typedef long long ll;
25 typedef pair<int, int> pii;
26 typedef pair<unsigned int,unsigned int> puu;
27 typedef pair<int, double> pid;
28 typedef pair<ll, int> pli;
29 typedef pair<int, ll> pil;
30 
31 const int INF = 0x3f3f3f3f;
32 const double eps = 1E-6;
33 const int LEN = 100010;
34 vector<pii> Map[LEN];
35 int dp[LEN][11], N, S, K;
36 
37 void dfs(int v, int f){
38     for(int i=0; i<Map[v].size(); i++){
39         int ch = Map[v][i].first, val = Map[v][i].second;
40         if(ch != f){
41             dfs(ch, v);
42             for(int k=K; k>=0; k--){
43                 dp[v][k] += dp[ch][0] + 2*val;
44                 for(int j=1; j<=k; j++){
45                     dp[v][k] = min(dp[v][k], dp[v][k-j] + dp[ch][j] + j*val);
46                 }
47             }
48         }
49     }
50 }
51 
52 int main()
53 {
54 //    freopen("in.txt", "r", stdin);
55 
56     int a, b, c;
57     while(scanf("%d%d%d", &N, &S, &K)!=EOF){
58         memset(dp, 0, sizeof dp);
59         for(int i=0; i<LEN; i++) Map[i].clear();
60         for(int i=0; i<N-1; i++){
61             scanf("%d%d%d", &a, &b, &c);
62             Map[a].PB(MP(b, c));
63             Map[b].PB(MP(a, c));
64         }
65         dfs(S, -1);
66         printf("%d\n", dp[S][K]);
67     }
68     return 0;
69 }
View Code

 

posted @ 2014-04-03 19:53  张小豪  阅读(135)  评论(0编辑  收藏  举报