[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;
}

 

posted @ 2018-05-14 19:59  void_f  阅读(137)  评论(0编辑  收藏  举报