题意:给出一棵树,边上有容量限制,求以任一点作为根和源点,叶子作为汇点的最大流的最大值

首先上网络流等于找死

树形DP可以\(O(n)\)求出以某点\(u\)为根的最大流,只需设\(f[u]=\sum min(cap_{u→v},f[v])\),

这是一个自底向上的过程

其中存在\(min\)是因为\(f[v]\)不包含连向\(u\)的边,要保证合法增广,

注意如果\(v\)为叶子则直接加上\(cap_{u→v}\)

此时我们也得知\(f[v]\)是以v为根的子树的最大流

那么换根后显然以\(v\)为整棵树的根时,最大流\(g[v]\)至少包含\(f[v]\),还有指向父亲\(u\)部分的贡献,这部分的贡献有原式可以比较得出为\(min(cap_{u→v},g[u]-min(cap_{u→v},f[v]))\),同理叶子需要特判,且\(f[root]=g[root]\)

这是一个自顶向下的过程

由此只需\(O(n)\)扫两遍就能得出任一点作为源点的最大流

另外由于POJ过于垃圾请交C++

PS.换根对于贡献的处理也可用于数据结构上,比如以任一点为根的前提下的对子树查询

详见https://blog.csdn.net/fsss_7/article/details/51076282

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define rrep(i,j,k) for(int i=j;i>=k;i--)
#define erep(i,u) for(int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
#define println(a) printf("%lld\n",(ll)(a))
using namespace std;
const int MAXN = 2e5+11;
const int MOD = 1e9+7;
typedef long long ll;
unsigned int xjb=2333333;
int Rand(){
return (xjb=xjb*12345+23333)%MOD+1;
}
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int to[MAXN<<1],nxt[MAXN<<1],cost[MAXN<<1],head[MAXN],tot;
int deg[MAXN];
void add(int u,int v,int w){
to[tot]=v;
cost[tot]=w;
nxt[tot]=head[u];
head[u]=tot++;
}
void init(){
memset(head,-1,sizeof head);
tot=0;
}
ll f[MAXN],g[MAXN],n;
void DP(int u,int fa){
f[u]=0;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i];
ll w=cost[i];
if(v==fa) continue;
DP(v,u);
if(deg[v]==1) f[u]+=w;
else f[u]+=min(w,f[v]);
}
}
void dfs(int u,int fa){
for(int i=head[u];~i;i=nxt[i]){
int v=to[i];
ll w=cost[i];
if(v==fa) continue;
g[v]=f[v];
if(deg[u]==1) g[v]+=w;
else g[v]+=min(w,g[u]-min(w,f[v]));
dfs(v,u);
}
}
int main(){
int T=0; cin>>T;
while(T--){
init();
memset(deg,0,sizeof deg);
n=read();
rep(i,1,n-1){
int u=read();
int v=read();
int w=read();
add(u,v,w);
add(v,u,w);
deg[u]++;
deg[v]++;
}
DP(1,0);g[1]=f[1];
dfs(1,0);
ll ans=0;
rep(i,1,n) ans=max(ans,g[i]);
println(ans);
}
return 0;
}

POJ - 3585 树上最大流 换根法的更多相关文章

  1. poj3585树最大流——换根法

    题目:http://poj.org/problem?id=3585 二次扫描与换根法,一次dfs求出以某个节点为根的相关值,再dfs遍历一遍树,根据之前的值换根取最大值为答案. 代码如下: #incl ...

  2. POJ 3585 Accumulation Degree【换根DP】

    传送门:http://poj.org/problem?id=3585 题意:给定一张无根图,给定每条边的容量,随便取一点使得从这个点出发作为源点,发出的流量最大,并且输出这个最大的流量. 思路:最近开 ...

  3. poj 3585 Accumulation Degree(二次扫描和换根法)

    Accumulation Degree 大致题意:有一棵流量树,它的每一条边都有一个正流量,树上所有度数为一的节点都是出口,相应的树上每一个节点都有一个权值,它表示从这个节点向其他出口可以输送的最大总 ...

  4. 题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)

    写一篇题解,以纪念调了一个小时的经历(就是因为边的数组没有乘2 phhhh QAQ) 题目 题目大意:找一个点使得从这个点出发作为源点,流出的流量最大,输出这个最大的流量. 以这道题来介绍二次扫描和换 ...

  5. cf219d 基础换根法

    /*树形dp换根法*/ #include<bits/stdc++.h> using namespace std; #define maxn 200005 ]; int root,n,s,t ...

  6. poj - 3585(二次扫描与换根法)

    周末牛客挂了个更难的,这个简单一些 #include<iostream> #include<cstring> #include<cstdio> #include&l ...

  7. 【51Nod1405】树上距离和 二次扫描与换根法

    题目大意:给定一棵 N 个点的边权均为 1 的树,依次输出每个点到其他各个点的距离和. 题解:首先任意选定一个节点为根节点,比如 1,第一遍 dfs 遍历树求出子树大小.树上前缀和.第二遍 dfs 遍 ...

  8. POJ3585 Accumulation Degree(二次扫描与换根法)

    题目:http://poj.org/problem?id=3585 很容易想出暴力.那么就先扫一遍. 然后得到了指定一个根后每个点的子树值. 怎么转化利用一下呢?要是能找出当前点的父亲的 “ 不含当前 ...

  9. $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法

    Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...

随机推荐

  1. STL中 set 和 multiset

    1. 所在头文件: <set>, 命名空间: std ; 声明如下: namespace std{ template <class T, class Compare = less&l ...

  2. wireshark问题

    上一篇wireshark编译成功了,生成了相应的wireshark.exe,dumpcap.exe等可执行文件(这些文件都是可以运行的),编译工具用的是VS2010,但是新生成的文件和文件夹中没有找到 ...

  3. python操作mysql数据库系列-安装MySQLdb

    一波三折,先是pip命令出现问题,然后各种方法尝试解决.然后是直接使用pip2命令安装报错,mysql-python库安装再次出现问题.于是使用国内镜像的方式去安装:pip2 install MySQ ...

  4. osg反走样

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits-& ...

  5. CentOS7 Failed to start LSB: Bring up/down

    原文地址:http://addam.blog.51cto.com/5041993/1839518 刚刚装好的虚拟机突然不能上网了,报错很诡异,具体报错如下: /etc/init.d/network r ...

  6. 特征工程 vs. 特征提取

    “特征工程”这个华丽的术语,它以尽可能容易地使模型达到良好性能的方式,来确保你的预测因子被编码到模型中.例如,如果你有一个日期字段作为一个预测因子,并且它在周末与平日的响应上有着很大的不同,那么以这种 ...

  7. 在 CentOS 上部署 Nginx 环境

    这里的案例主要通过虚拟机( vmware workstation (14) )的方式安装 Center OS 到本地环境 资源下载:  vmware workstation   / CentOS 本次 ...

  8. C#中遇到的方法总结

    1.Select(string filterExpression, string sort)  // 获取按照指定的排序顺序且与筛选条件相匹配的所有 System.Data.DataRow 对象的数组 ...

  9. ThinkJS 中的Logic层

    第一个为什么需要Logic层: 当在 Action 里处理用户的请求时,经常要先获取用户提交过来的数据,然后对其校验,如果校验没问题后才能进行后续的操作:当参数校验完成后,有时候还要进行权限判断等,这 ...

  10. WebCalendar.js

    var cal;   var isFocus=false; //是否为焦点   var pickMode ={       "second":1,       "minu ...