在递归过程中也把子节点的贡献(以及左右国家数记录下来了)。
void dfs(int u,int fa) {
d[u]=1;//当前节点也算一个
for(int i=h[u]; i; i=ne[i]) {
int to=e[i];//子节点
if(to==fa) continue;//防止重复搜索,即防止从下往上搜
dfs(to,u);//子节点
//这样子先递归,在加上权,解释为先一路递归的叶节点,然后一路返回,从下往上推
//并执行下方的加法
//有点树形dp的味道
d[u]+=d[to];//在递归的过程中就把每个边的贡献的算了记录
ans=ans+w[i]*abs(2*d[to]-n);//结算贡献和
}
}
ACcode:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e6+10;
int h[N],w[N],e[N],ne[N],cnt,n,ans,d[N];
void add(int u,int v,int ww) {
e[++cnt]=v,w[cnt]=ww,ne[cnt]=h[u],h[u]=cnt;
}
void dfs(int u,int fa) {
d[u]=1;//当前节点也算一个
for(int i=h[u]; i; i=ne[i]) {
int to=e[i];
if(to==fa) continue;//防止重复搜索,即防止从下往上搜
dfs(to,u);//子节点
d[u]+=d[to];//在递归的过程中就把每个边的贡献的算了记录
ans=ans+w[i]*abs(2*d[to]-n);//结算贡献和
}
}
void solve() {
cin>>n;
for(int i=1; i<=n-1; i++) {
int a,b,c;
cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
}
dfs(1,0);
cout<<ans<<"\n";
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int tt=1;
//cin>>tt;
while(tt--)
solve();
return 0;
}
over~