当前位置: 代码迷 >> 综合 >> 【BZOJ1060】[ZJOI2007]时态同步
  详细解决方案

【BZOJ1060】[ZJOI2007]时态同步

热度:6   发布时间:2024-01-13 09:54:55.0

题目链接:传送门
题解:
树形DP,用f[u]表示u及其子树中dis的最大值,发现选取的边越靠近根越优,所以对于一条边(u,v),如果f[u]>f[v],那么显然这条边对于答案的贡献是f[u]-f[v]

//by sdfzchy
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int inf=(1<<30),N=2000100,mod=1e9+7;
int n,m,s,ecnt,head[N];
inline int in()
{char tmp=getchar();int res=0,f=1;while((tmp<'0'||tmp>'9')&&tmp!='-')tmp=getchar();if(tmp=='-') f=-1,tmp=getchar();while(tmp>='0'&&tmp<='9')   res=(res<<1)+(res<<3)+(tmp^48),tmp=getchar();return res*f;
}
LL ans,f[N],dis[N];
struct E
{int v,nxt,w;
}e[N<<1];
void add(int u,int v,int w)
{++ecnt;e[ecnt]=(E){v,head[u],w};head[u]=ecnt;
}
void dfs(int u,int fa)
{f[u]=dis[u];for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(v==fa) continue;dis[v]=dis[u]+e[i].w;dfs(v,u);f[u]=max(f[u],f[v]);}
}void gi(int u,int fa)
{for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(v==fa) continue;if(f[u]>f[v]) ans+=f[u]-f[v];gi(v,u);}
}
int main()
{n=in(),s=in();for(int i=1,u,v,w;i<n;i++){u=in(),v=in(),w=in();add(u,v,w);add(v,u,w);}dfs(s,s);gi(s,s);printf("%lld",ans);return 0;
}