分析 : 画一画图可以知道下面这种方式总和最小
对同一父亲节点的儿子们,尽量兄弟之间互相连,如果有儿子落单就和父亲连起来。
DFS一遍即可
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10005;
int head[maxn],cnt[maxn],tot;
ll ans;
struct Edge {
int Next,to,w;
}e[maxn<<1];
void add(int x,int y,int z)
{
e[++tot].to=y,e[tot].w=z,e[tot].Next=head[x],head[x]=tot;
//ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
}
void dfs(int x,int fa,int dis)
{
int y;
cnt[x]=1;//cnt[x]为以x为根包含x在内的子树节点数量
for(int i=head[x];i;i=e[i].Next) {
y=e[i].to;
if(y==fa) continue;
dfs(y,x,e[i].w);
cnt[x]+=cnt[y];
}
if(cnt[x]%2) ans+=dis;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,x,y;
ll z;
scanf("%d",&n);
ans=tot=0;
for(int i=0;i<=n;i++) head[i]=cnt[i]=0;
for(int i=1;i<n;i++) {
scanf("%d%d%lld",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dfs(1,0,0);
printf("%lld\n",ans);
}
return 0;
} 
京公网安备 11010502036488号