给出一棵n个点的树,将这n个点两两配对,求所有可行的方案中配对两点间的距离的总和最大为多少。
Input
一个数n(1<=n<=100,000,n保证为偶数) 接下来n-1行每行三个数x,y,z表示有一条长度为z的边连接x和y(0<=z<=1,000,000,000)
Output
一个数表示答案
Input示例
6 1 2 1 1 3 1 1 4 1 3 5 1 4 6 1
Output示例
7 //配对方案为(1,2)(3,4)(5,6)
#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
typedef long long ll;
struct Edge{
Edge(){
}
Edge(int a, int b, int c){
from = a;
to = b;
d = c;
}
int from, to, d;
};
vector<Edge> v[maxn];
int p[maxn], n;
ll ans;
void dfs(int j, int f){
p[j] = 1;
for(int i = 0; i < v[j].size(); i++){
Edge a = v[j][i];
if(a.to != f){
dfs(a.to, j);
p[j] += p[a.to];
}
}
}
void Dfs(int j, int f){
for(int i = 0; i < v[j].size(); i++){
Edge a = v[j][i];
if(a.to != f){
ans += min(n-p[a.to], p[a.to]) * (ll)a.d;
Dfs(a.to, j);
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
int a, b, c;
scanf("%d", &n);
for(int i = 0; i < n-1; i++){
scanf("%d%d%d", &a, &b, &c);
v[a].push_back(Edge(a, b, c));
v[b].push_back(Edge(b, a, c));
}
dfs(1, -1);
Dfs(1, -1);
cout << ans << endl;
}