传送门:CodeForces-1281E
思路分析
对于每条边单独计算贡献,假设u–>v,u左侧有x个点,v右侧有y个点
- 最大:尽量让这条边用很多次,那么最多能用min$(x,y)$次
- 最小:让相邻的两两配对一定是最小的,如果y为奇数,那么x一定也是奇数,那么v右侧可以两两配对剩一个v,u左侧同理,所以u,v配对
样例输入
2
3
1 2 3
3 2 4
2 4 3
4 5 6
5 6 5
2
1 2 1
1 3 2
1 4 3
样例输出
15 33
6 6
AC代码
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <string>
#include <cstdio>
#include <chrono>
#include <random>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define ls x<<1
#define rs x<<1|1
#define fi first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define fun function
#define sz(x) x.size()
#define lowbit(x) x&(-x)
#define all(x) x.begin(),x.end()
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int INF = 0x3f3f3f3f;
const int N=1e6+10;
vector<pair<ll,ll>>e[N];
ll mi,ma,n,siz[N];
void dfs(int u,int fa){
siz[u]=1;
for(auto x:e[u]){
ll v=x.fi;
ll w=x.se;
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
if(siz[v]&1) mi+=w;
ma+=min(siz[v],n-siz[v])*w;
}
}
int main() {
IOS;
#ifdef xiaofan
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
int t;
cin>>t;
while(t--){
cin>>n;
n*=2;
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<n;i++){
ll u,v,w;
cin>>u>>v>>w;
e[u].push_back(mp(v,w));
e[v].push_back(mp(u,w));
}
mi=0,ma=0;
dfs(1,1);
cout<<mi<<" "<<ma<<endl;
}
return 0;
}