Solution
n个点n-1条双向边明显是树,而且保证必定是偶数个节点,那么就肯定是两两配对。
就一个节点来说,跟兄弟节点配对,或者跟父亲节点配对肯定是最优的。
所以只需要判断节点所在子树里面的节点数是否为偶数,如果是偶数说明不用和此节点的父亲节点配对,若为奇数则需要加上这条边,那么可设 dp[i] 为以 i 为根节点的子树的配对后的路径和,dfs下去判断子树节点即可。

Code

#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define inf 0x3f3f3f3f
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
void put1(){ puts("Yes") ;}void put2(){ puts("No") ;}void put3(){ puts("-1"); }

const int manx=1e4+5;
const int mo=998244353;

vector<pair<ll,ll> >g[manx];
ll cnt[manx],ans;

void dfs(ll u,ll pre,ll res){
    cnt[u]=1;
    for(auto x: g[u]){
        ll v=x.fi,w=x.se;
        if(v==pre) continue;
        dfs(v,u,w);
        cnt[u]+=cnt[v];
    }
    if(cnt[u]&1) ans+=res;
}
int main()
{
    ll p=read();
    while(p--){
        ll n=read();
        for(int i=1;i<=n;i++) g[i].clear();
        for(int i=1;i<n;i++){
            ll u=read(),v=read(),w=read();
            g[u].pb(mp(v,w)); g[v].pb(mp(u,w));
        }
        ans=0;
        dfs(1,0,0);
        printf("%lld\n",ans);
    }
    return 0;
}