[BZOJ1060][ZJOI2007]时态同步(树形DP)
因为边权只能增加,那么设f[u]为u子树上从i出发到达某个叶节点的最大路径,
显然Ans应该增加f[u]-f[v]-e[i].w
Code
#include <cstdio> #include <algorithm> #define N 500010 using namespace std; struct info{int to,nex,w;}e[N*2]; int n,tot,head[N],rt; long long f[N],Ans; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void Link(int u,int v,int w){ e[++tot].to=v;e[tot].w=w;e[tot].nex=head[u];head[u]=tot; } void dfs(int u,int fa){ for(int i=head[u];i;i=e[i].nex){ int v=e[i].to; if(v==fa) continue; dfs(v,u); f[u]=max(f[u],f[v]+e[i].w); } for(int i=head[u];i;i=e[i].nex) if(e[i].to!=fa) Ans+=f[u]-f[e[i].to]-e[i].w; } int main(){ n=read(),rt=read(); for(int i=1;i<n;++i){ int u=read(),v=read(),w=read(); Link(u,v,w),Link(v,u,w); } dfs(rt,0); printf("%lld\n",Ans); return 0; }