给出
n
≤
5
e
5
n\leq5e5
n≤5e5个点的一颗树,然后每次可以多花费一次代价给一条边
+
1
+1
+1,求问最终使得从根出发到所有叶子结点距离都相同的最小花费是多少。
一个结论是:每个子树都满足从根出发到叶子结点相同的这个条件,而且这个距离即为根到叶子结点最远的距离。
预处理出每个点到叶子结点的最远距离。然后有转移
f
u
=
∑
v
∈
s
o
n
u
f
v
+
d
u
−
d
v
−
e
u
,
v
f_{u}=\sum\limits_{v\in son_{u}}f_{v}+d_{u}-d_{v}-e_{u,v}
fu=v∈sonu∑fv+du−dv−eu,v。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=5e5+7;
struct edge{
int v,w;
};
vector<edge> go[N];
int dis[N];
ll f[N];
void dfs1(int u,int fa) {
for(auto &e:go[u]) {
int v=e.v,w=e.w;
if(v==fa) continue;
dfs1(v,u);
dis[u]=max(dis[u],dis[v]+w);
}
}
void dfs2(int u,int fa) {
for(auto &e:go[u]) {
int v=e.v,w=e.w;
if(v==fa) continue;
dfs2(v,u);
f[u]+=f[v]+dis[u]-dis[v]-w;
}
}
int main() {
int n,s;
scanf("%d%d",&n,&s);
for(int i=1;i<n;i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
go[u].push_back({v,w});
go[v].push_back({u,w});
}
dfs1(s,-1);
dfs2(s,-1);
printf("%lld\n",f[s]);
return 0;
}