除了源点之外,树中所有度数为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;
 	 }
 }
 
 
 

 

posted on 2023-02-27 00:06  towboat  阅读(20)  评论(0)    收藏  举报