P1131 [ZJOI2007]时态同步

${\color{cyan}{>>Question}}$

题意让我们用最少的代价把叶子节点到根节点的距离调成相同

每次向最长链看齐即可

令$f[u]$表示以$u$为根到叶节点的最长链长度

则$$f[u] = max\left\{f[v]+e(u,v)\right\}$$

统计答案

$$ans = \sum _{v(e(u,v)\in E)} f[u]-(f[v]+e(u,v))$$

上代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #define ll long long
 6 using namespace std; 
 7 
 8 template <typename T> void in(T &x) {
 9     x = 0; T f = 1; char ch = getchar();
10     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
11     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
12     x *= f;
13 }
14 
15 template <typename T> void out(T x) {
16     if(x < 0) x = -x , putchar('-');
17     if(x > 9) out(x/10);
18     putchar(x%10 + 48);
19 }
20 //-------------------------------------------------------
21 
22 const int N = 5e5+7;
23 
24 int n,s;
25 ll ans,f[N];
26 
27 struct edge {
28     int v,w,nxt;
29     edge(int v = 0,int w = 0,int nxt = 0):v(v),w(w),nxt(nxt){};
30 }e[N<<1]; int head[N],e_cnt;
31 
32 void add(int u,int v,int w) {
33     e[++e_cnt] = edge(v,w,head[u]); head[u] = e_cnt;
34 }
35 
36 void dfs(int u,int fa) {
37     int i;
38     int max_e = 0;
39     for(i = head[u]; i;i = e[i].nxt) {
40         int v = e[i].v; if(v == fa) continue;
41         dfs(v,u);
42         f[u] = max(f[u],f[v]+e[i].w);
43     }
44     for(i = head[u]; i;i = e[i].nxt) {
45         int v = e[i].v; if(v == fa) continue;
46         ans += f[u] - (f[v]+e[i].w);
47     }
48 }
49 
50 int main() {
51     int i,u,v,w;
52     in(n); in(s);
53     for(i = 1;i < n; ++i) {
54         in(u); in(v); in(w);
55         add(u,v,w); add(v,u,w);
56     }
57     dfs(s,0);
58     out(ans);
59     return 0;
60 }

 

posted @ 2019-08-15 08:35  陈星卿  阅读(166)  评论(0编辑  收藏  举报