hdu 4118(树形dp) 成都现场赛H题

题意:有一棵带权树每个节点上住着一个人。人后需要让所有人交换房子,但是每个结点只住一个人。问你所有人最长走多少路。

思路:这里有一个贪心就是每条边的权值乘以两边结点少的那一边的两倍。然后就是dfs求出每个结点子树上有多少点这样n-dp[v]就是另一边的点了。注意longlong和手动加栈。

代码如下:

 1 /**************************************************
 2  * Author     : xiaohao Z
 3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
 4  * Last modified : 2014-03-23 22:14
 5  * Filename     : hdu_chengdu1.cpp
 6  * Description     : 
 7  * ************************************************/
 8 
 9 #pragma comment(linker, "/STACK:1024000000,1024000000")
10 #include <iostream>
11 #include <cstdio>
12 #include <cstring>
13 #include <cstdlib>
14 #include <cmath>
15 #include <algorithm>
16 #include <queue>
17 #include <stack>
18 #include <vector>
19 #include <set>
20 #include <map>
21 #define MP(a, b) make_pair(a, b)
22 #define PB(a) push_back(a)
23 
24 using namespace std;
25 typedef long long ll;
26 typedef pair<int, int> pii;
27 typedef pair<unsigned int,unsigned int> puu;
28 typedef pair<int, double> pid;
29 typedef pair<ll, int> pli;
30 typedef pair<int, ll> pil;
31 
32 const int INF = 0x3f3f3f3f;
33 const double eps = 1E-6;
34 const int LEN = 100000+10;
35 vector<pii> Map[LEN];
36 int n, depth[LEN], dp[LEN], edge[LEN][3];
37 
38 int dfs(int v, int f, int d){
39     depth[v] = d;
40     int ret = 1;
41     for(int i=0; i<Map[v].size(); i++){
42         if(Map[v][i].first!=f) ret+=dfs(Map[v][i].first, v, d+1);
43     }
44     dp[v] = ret;
45     return ret;
46 }
47 
48 int main()
49 {
50 //    freopen("in.txt", "r", stdin);
51 
52     ios::sync_with_stdio(false);
53     int T, kase = 1, a, b, c;
54     cin >> T;
55     while(T--){
56         for(int i=0; i<LEN; i++) Map[i].clear();
57         cin >> n;
58         for(int i=0; i<n-1; i++){
59             cin >> a >> b >> c;
60             a--;b--;
61             edge[i][0] = a;edge[i][1] = b;edge[i][2] = c;
62             Map[a].PB(MP(b, c));
63             Map[b].PB(MP(a, c));
64         }
65         dfs(0, -1, 0);
66         ll ans = 0;
67         for(int i=0; i<n-1; i++){
68             a = edge[i][0]; b = edge[i][1];
69             c = (depth[a] > depth[b] ? dp[a] : dp[b]);
70             ans += (min(c, n-c)*2*edge[i][2]);
71         }
72         cout << "Case #" << kase++ << ": ";
73         cout << ans << endl;
74     }
75     return 0;
76 }
View Code

 

posted @ 2014-03-23 23:22  张小豪  阅读(252)  评论(0编辑  收藏  举报