传送门
换根dp板子题(板子型选手
题意:
一棵树确定源点和汇点找到最大的流量(拿出一整套最大瘤板子orz
const int maxn=2e5+10; int head[maxn],tot; struct node { int nt,to;long long w; }q[2*maxn]; long long dp[maxn];int cnt[maxn]; void insert(int u,int v,long long w) { q[tot].nt=head[u];q[tot].w=w;q[tot].to=v;head[u]=tot++; q[tot].nt=head[v];q[tot].w=w;q[tot].to=u;head[v]=tot++; } long long ans; void dfs(int u,int fa) { //cout<<u<<endl; for(int i=head[u];i!=-1;i=q[i].nt){ int v=q[i].to;long long w=q[i].w; if(v==fa) continue; dfs(v,u); if(cnt[v]==1) dp[u]+=w; else dp[u]+=min(w,dp[v]); //cout<<u<<" "<<dp[u]<<endl; } } void dfs1(int u,int fa) { //cout<<u<<" "<<dp[u]<<endl; ans=max(ans,dp[u]); for(int i=head[u];i!=-1;i=q[i].nt){ int v=q[i].to;long long w=q[i].w; if(v==fa) continue; dp[v]+=min(w,dp[u]-min(dp[v],w)); dfs1(v,u); } } int main() { int t;scanf("%d",&t); while(t--){ int n;scanf("%d",&n);ans=0; for(int i=1;i<=n;i++) head[i]=-1,cnt[i]=0,dp[i]=0;tot=0; for(int i=1;i<n;i++){ int t1,t2;long long t3;scanf("%d%d%lld",&t1,&t2,&t3); insert(t1,t2,t3);cnt[t1]++;cnt[t2]++; } dfs(1,0); dfs1(1,0); cout<<ans<<endl; } }
原文地址:https://www.cnblogs.com/r138155/p/12639253.html
时间: 2024-10-01 04:45:45