题目链接:http://poj.org/problem?id=3585;
/*
题意:找一个点使得,使得从这个点出发作为源点,发出的流量最大,输出这个最大的流量。
思路:设pd[x]为以x为根的子树中,把x作为源点,从x发出的流量的最大值,dfs一次得到。
转移方程:
pd[x]+= in[y]==1?w :min(pd[y],w)
(x的所有儿子)
设dp[x]为以x作为整棵树的根是所求的答案,dfs一次得到
首先 dp[root]=pd[root]
转移过程:
dp[y]=pd[y]+in[x]==1?w :min(dp[x]−min(pd[y],w),w)
*/
#include<cstring>
#include<string>
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
const int N=2e5+10;
struct node
{
int v,ne,w;
} q[N*2];
int e,f[N];
int dp[N],pd[N],in[N],n,ans;
void add(int a,int b,int c)
{
q[++e].v=b;
q[e].w=c;
q[e].ne=f[a];
f[a]=e;
}
void dfs(int u,int pre)
{
for(int i=f[u];i!=-1;i=q[i].ne)
{
int v=q[i].v,w=q[i].w;
if(v==pre) continue;
dfs(v,u);
if(in[v]==1)
pd[u]+=w;
else
pd[u]+=min(pd[v],w);
}
}
void dfs2(int u,int pre)
{
for(int i=f[u];i!=-1;i=q[i].ne)
{
int v=q[i].v,w=q[i].w;
if(v==pre) continue;
if(in[u]==1)
dp[v]=w+pd[v];
else
dp[v]=pd[v]+min(dp[u]-min(pd[v],w),w);
dfs2(v,u);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ans=0;
memset(f,-1,sizeof(f));
memset(dp,0,sizeof(dp));
memset(pd,0,sizeof(pd));
memset(in,0,sizeof(in));
e=0;
int a,b,c;
scanf("%d",&n);
for(int i=1; i<n; i++)
{
scanf("%d %d %d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
in[a]++;
in[b]++;
}
int root=1;
dfs(root,0);
dp[root]=pd[root];
dfs2(root,0);
for(int i=1; i<=n; i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
}
return 0;
}