除了源点之外,树中所有度数为1
的节点都是入海口,可以吸收无限多的水,我们称之为汇点。
也就是说,水系中的水从源点出发,沿着每条河道,最终流向各个汇点。
问最大流量
f[ x] = sum{ min( f[y] ,z) }
换根,考虑 g[x] 流向所有(包括x往上) 时的最大流量
g[y]=f[y]+ min( z, g[x]- min(z, f[y]) )
#include <iostream>
#include <cstring>
using namespace std;
const int N=2e5+30,M=2*N;
int all,hd[N],w[M],nxt[M],go[M],n;
int g[N],f[N],in[N];
void add(int x,int y,int z){
go[++all]=y,nxt[all]=hd[x],hd[x]=all;
w[all]=z;
}
void dp(int x,int fa){
int y,z,i;
f[x]=0;
for(i=hd[x];i;i=nxt[i]){
y=go[i],z=w[i]; if(y==fa) continue;
dp(y,x);
if(in[y]<=1) f[x]+=z;
else f[x]+=min(z,f[y]);
}
}
void dfs(int x,int fa){
int y,z,i;
for(i=hd[x];i;i=nxt[i]){
y=go[i],z=w[i]; if(y==fa) continue;
if(in[x]==1) g[y]=z+f[y];
else g[y]=f[y]+min(g[x]-min(f[y],z),z);
dfs(y,x);
}
}
signed main(){
int i,tes;
cin>>tes;
while(tes--){
cin>>n;
int x,y,z;
for(i=1;i<=n;i++) f[i]=g[i]=in[i]=hd[i]=0;
all=0;
for(i=1;i<n;i++)
cin>>x>>y>>z,add(x,y,z),add(y,x,z),
in[y]++,in[x]++;
dp(1,-1);
g[1]=f[1];
dfs(1,-1);
int ans=0;
for(i=1;i<=n;i++) ans=max(ans,g[i]);
cout<<ans<<endl;
}
}
浙公网安备 33010602011771号