bzoj 1060: [ZJOI2007]时态同步 树形dp

来源:互联网 发布:玛祖铭立 知乎 编辑:程序博客网 时间:2024/05/21 00:16

题意

给出一棵有根树,边有边权。每次操作可以使得某条边的长度+1,问多少次操作后所有叶节点的深度相等。
n<=500000

分析

直接树形dp即可。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N=500005;int n,root,cnt,last[N];LL dep[N],mx[N],ans;struct edge{int to,w,next;}e[N*2];void addedge(int u,int v,int w){    e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;    e[++cnt].to=u;e[cnt].w=w;e[cnt].next=last[v];last[v]=cnt;}void dfs(int x,int fa){    mx[x]=dep[x];    for (int i=last[x];i;i=e[i].next)    {        if (e[i].to==fa) continue;        dep[e[i].to]=dep[x]+e[i].w;        dfs(e[i].to,x);        mx[x]=max(mx[x],mx[e[i].to]);    }    for (int i=last[x];i;i=e[i].next)    {        if (e[i].to==fa) continue;        ans+=mx[x]-mx[e[i].to];    }}int main(){    scanf("%d%d",&n,&root);    for (int i=1;i<n;i++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        addedge(x,y,z);    }    dfs(root,0);    printf("%lld",ans);    return 0;}