树形DP Gym 100496H House of Representatives

 

题目传送门

 1 /*
 2     题意:寻找一个根节点,求min f(u) = ∑ρ(v, u) * p(v)。ρ(v, u)是u到v的距离,p(v)是v点的权值
 3     树形DP:先从1出发遍历第一次,sum[u]计算u到所有子节点v的路径权值(之后的点路径有叠加,所以先把路径权值加后*w),
 4             计算f[u](缺少u节点以上的信息)。然后再遍历一遍,之前是DFS从下往上逆推,现在是顺推,把u节点以上的信息加上
 5     dp的部分不是很多,两个DFS函数想了很久,还是没完全理解:(
 6 */
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <algorithm>
10 #include <vector>
11 using namespace std;
12 
13 typedef long long ll;
14 const int MAXN = 1e5 + 10;
15 const int INF = 0x3f3f3f3f;
16 int p[MAXN];
17 ll f[MAXN];
18 ll sum[MAXN];
19 vector<pair<int, int> > G[MAXN];
20 
21 void DFS1(int u, int rt)
22 {
23     f[u] = 0;    sum[u] = p[u];
24     for (int i=0; i<G[u].size (); ++i)
25     {
26         int v = G[u][i].first;    int w = G[u][i].second;
27         if (v == rt)    continue;
28         DFS1 (v, u);
29         f[u] += f[v] + sum[v] * w;    sum[u] += sum[v];
30     }
31 }
32 
33 void DFS2(int u, int rt)
34 {
35     for (int i=0; i<G[u].size (); ++i)
36     {
37         int v = G[u][i].first;    int w = G[u][i].second;
38         if (v == rtGym 100496H House of Representatives)    continue;
39         f[v] = f[u] - sum[v] * w + (sum[u] - sum[v]) * w;
40         sum[v] = sum[u];
41         DFS2 (v, u);
42     }
43 }
44 
45 int main(void)        //Gym 100496H House of Representatives
46 {
47 //    freopen ("H.in", "r", stdin);
48     freopen ("house.in", "r", stdin);
49     freopen ("house.out", "w", stdout);
50 
51     int n;
52     while (scanf ("%d", &n) == 1)
53     {
54         for (int i=1; i<=n; ++i)    scanf ("%d", &p[i]);
55         for (int i=1; i<=n; ++i)    G[i].clear ();
56 
57         for (int i=1; i<=n-1; ++i)
58         {
59             int u, v, w;    scanf ("%d%d%d", &u, &v, &w);
60             G[u].push_back (make_pair (v, w));
61             G[v].push_back (make_pair (u, w));
62         }
63 
64         DFS1 (1, -1);    DFS2 (1, -1);
65 
66         int p = 1;
67         for (int i=2; i<=n; ++i)
68         {
69             if (f[i] < f[p])    p = i;
70         }
71 
72         printf ("%d %I64d\n", p, f[p]);
73     }
74 
75     return 0;
76 }

 

posted @ 2015-07-14 17:33  Running_Time  阅读(208)  评论(0编辑  收藏  举报