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

首先上网络流等于找死

树形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. 633E Binary Table

    传送门 分析 我们发现n特别小,所以可以从这里入手 我们记录出所有列中某一种状态的列有多少个 我们再记录出每种列最少有多少个1(原来的1的个数和取反后的个数去最小值) 于是我们可以得出对于所有列异或一 ...

  2. [GO]结构体成员的使用:普通变量

    package main import "fmt" func main() { type student struct { id int name string sex byte ...

  3. jquery 常用工具方法

    inArray(value, array [, fromIndex ])方法类似于原生javascript的indexOf()方法,没有找到匹配元素时它返回-1.如果数组第一个元素匹配参数,那么$.i ...

  4. 20169205实验二 Java面向对象程序设计

    20169205实验二 Java面向对象程序设计 实验内容及步骤 (一)单元测试 1.三种代码 伪代码:以简洁的自然语言表明设计步骤: 产品代码:用以实现特定功能的程序或机器语言: 测试代码:用以对产 ...

  5. Java NIO学习-详细内容(三)

    九.nio.file 该包是1.7新出的,包含了一系列高级的文件和目录操作方法 1.控制目录属性,只读,系统之类的 2.监控文件及文件夹的改变的WatchService public void sta ...

  6. [Windows] IIS6 部署ISAPI

    环境: OS:Windows Server 2003  Enterprise sp2 34位 IIS:6.0 ISAPI: delphi xe 编译的webbroker isapi dll 32位 ( ...

  7. 文件查找记录类型 - TSearchRec - 文件操作(二)

    SysUtils单元下的TSearchRec是一个记录类型,主要通过FindFirst, FindNext, and FindClose使用. 接上一篇举例说明TSearchRec常用成员 //sys ...

  8. Reporting Service服务SharePoint集成模式安装配置(9、PowerPivot for SharePoint 安装配置详细)

    PowerPivot for SharePoint 增加了对发布到 SharePoint 中的 PowerPivot 工作簿的协作和文档管理支持. PowerPivot for SharePoint ...

  9. Transaction And Lock--由Lookup导致的死锁情况

    存在这样情况:1.表TB1有一列建立索引2.事务A对表进行更新,先获取对表的X锁以更新基本表中数据,然后对索引申请X锁以更新索引数据.3.事务B对表进行更新,先获取索引上S锁以使用索引进行Loopup ...

  10. docker swarm 命令

    初始化swarm manager并制定网卡地址 docker swarm init --advertise-addr 192.168.10.117 强制删除集群,如果是manager,需要加–forc ...