题意
给定一颗树,分成个点对,使得他们的距离和最小。
分析
显然不同点对之间不共用边的情况是最优的,如果有共用边,明显可以重新分配,使得距离和更小。
接下来考虑,显然如果子树大小是偶数的话,可以子树内部消化,如果是奇数,就要加上边权。
#include <bits/stdc++.h> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define pii pair<int,int> #define int long long const int inf = 0x3f3f3f3f; const int maxn = 201110; const int M = 1e9+7; int n,m,k,ok; vector<pii> v[maxn]; int sz[maxn]; int dfs(int u,int pre,int cost) { sz[u] = 1; int res = 0; for(auto i : v[u]) { if(i.first == pre) continue; res += dfs(i.first,u,i.second); sz[u] += sz[i.first]; } if(sz[u]%2) res += cost; return res; } signed main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin>>T; while(T--) { cin>>n; for(int i = 1,x,y,z; i < n; i++) { cin>>x>>y>>z; v[x].push_back({y,z}); v[y].push_back({x,z}); } cout<<dfs(1,0,inf)<<endl; for(int i = 1; i <= n; i++) { v[i].clear(); sz[i] = 0; } } return 0; }