题目链接:传送门
题解:
树形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;
}