Solution
由题意可知是一个树形结构。若要使两两之间边权最小,尽量不能选重边,也就是说尽可能在节点所在子树里寻找答案。
显然与叶子节点相连的边必须选。然后考虑其他边:
- 若一棵子树中的节点有偶数个,那么两两配对即可,不用添加新的边权。
- 若一棵子树有奇数个节点,那么根节点要和其他子树连边,所以还要加上根节点与其父节点之间的边的边权。
综上, 统计子树大小,偶数不用处理,奇数加边权即可。
数据范围较大,注意开 。
时间复杂度: 。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int maxn=1e4+10;
struct edge{
ll t,v,w;
}e[maxn<<1];
ll T,n,tot,ans,hd[maxn];
void add(ll x,ll y,ll z){
tot++;
e[tot].t=hd[x];
e[tot].v=y;
e[tot].w=z;
hd[x]=tot;
}
ll Dfs(ll u,ll fa,ll x){
ll cnt=1;
for(int i=hd[u];i!=0;i=e[i].t)
if(e[i].v!=fa)
cnt+=Dfs(e[i].v,u,e[i].w);
if(cnt%2)
ans+=x;
return cnt;
}
int main(){
ios::sync_with_stdio(false);
cin>>T;
ll x,y,z;
while(T--){
memset(hd,0,sizeof(hd));
ans=tot=0;
cin>>n;
for(int i=1;i<n;i++){
cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);
}
Dfs(1,0,0);
cout<<ans<<endl;
}
return 0;
} 
京公网安备 11010502036488号