山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 1060 [ZJOI2007]时态同步(树形DP)

 

【题目链接】

 

    http://www.lydsy.com/JudgeOnline/problem.php?id=1060

 

【题意】

 

    求最少的增加量,使得以rt为根的树中由一个结点出发的所有到叶子结点的路长相等

 

【思路】

 

    树形DP。

    设f[u]为以u为根的子树中到叶子的最大路长,只要把其他的所有路长都增加到f[u]就可以了。

 

【代码】

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 const int N = 5e5+10;
 8 
 9 struct Edge {
10     int v,w,nxt;
11 }e[N<<1];
12 int en=1,front[N];
13 void adde(int u,int v,int w) 
14 {
15     en++; e[en].v=v,e[en].w=w,e[en].nxt=front[u],front[u]=en;
16 }
17 
18 int n,rt;
19 int f[N]; ll ans;
20 
21 ll read()
22 {
23     char c=getchar(); ll f=1,x=0;
24     while(!isdigit(c)) {if(c=='-')f=-1; c=getchar();}
25     while(isdigit(c)) x=x*10+c-'0',c=getchar();
26     return x*f;
27 }
28 
29 void dfs(int u,int fa) {
30     for(int i=front[u];i;i=e[i].nxt) {
31         int v=e[i].v;
32         if(v!=fa) {
33             dfs(v,u);
34             f[u]=max(f[u],f[v]+e[i].w);
35         }
36     }
37     for(int i=front[u];i;i=e[i].nxt)
38         if(e[i].v!=fa) ans+=f[u]-f[e[i].v]-e[i].w;
39 }
40 
41 int main()
42 {
43     n=read(),rt=read();
44     for(int i=0;i<n-1;i++) {
45         int u=read(),v=read(),w=read();
46         adde(u,v,w),adde(v,u,w);
47     }
48     dfs(rt,-1);
49     printf("%lld\n",ans);
50     return 0;
51 }

 

合影留念 :)

 

 

posted on 2016-03-14 16:44  hahalidaxin  阅读(171)  评论(0编辑  收藏  举报