#include<cstdio>
#include<cstring>
#include<algorithm>
#define en '\n'
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int N=2e5+5;
struct Edge{int to,len,nex;}edge[N<<1];
int head[N],tot;
void add(int from,int to,int len){
edge[++tot]=(Edge){to,len,head[from]};head[from]=tot;
edge[++tot]=(Edge){from,len,head[to]};head[to]=tot;
}
int dp[N][2],in[N];//dp[x][0]:x流向子树的最大流量 dp[x][1]:x流向整棵树的最大流量
void dfs1(int x,int fa){
dp[x][0]=0;
for(int i=head[x];i;i=edge[i].nex){
int y=edge[i].to,len=edge[i].len;
if(y==fa) continue;
dfs1(y,x);
if(in[y]==1) {dp[x][0]+=len;continue;}
dp[x][0]+=min(len,dp[y][0]);
}
}
void dfs2(int x,int fa){
for(int i=head[x];i;i=edge[i].nex){
int y=edge[i].to,len=edge[i].len;
if(y==fa) continue;
if(in[x]==1) dp[y][1]=dp[y][0]+len;
else dp[y][1]=dp[y][0]+min(len,dp[x][1]-min(dp[y][0],len));
dfs2(y,x);
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
m(head,0),tot=0,m(in,0);
int n;scanf("%d",&n);
for(int i=1;i<=n-1;++i){
int x,y,w;scanf("%d%d%d",&x,&y,&w);
add(x,y,w);
++in[x],++in[y];
}
dfs1(1,1),dp[1][1]=dp[1][0],dfs2(1,1);
int ans=0;
for(int i=1;i<=n;++i) ans=max(ans,dp[i][1]);
printf("%d\n",ans);
}
}
POJ3585(Accumulation Degree 换根dp模板 所有点到所有点的容量)
最新推荐文章于 2020-04-17 01:30:15 发布