分析

记\(D_i\)为从\(S\)出发到\(i\)的最短路

最短路算法保证, 算法结束时

对于任意存在弧\((i,j)\)满足\(D_i + c_{ij}\ge D_j\) ①

且对于每个 \(j\) 至少存在一个 \(i\) 使得等号成立 ②

算法结束后, 恰在最短路上的边满足 \(D_j = D_i + c_{ij}\)

在最小费用流的计算中,我们每次沿 \(D_j = D_i + c_{ij}\)的路径增广

增广会让流量减小,会让部分的弧变得没有流量(即暂时不存在了)

是不会破坏①,但可能会破坏②的

这可能使我们找不到每条边都满足 $ D_j = D_i + c_{ij}$ 新的增广路

普通费用流的方法是:每次增广再使用 SPFA等方法重新计算\(D\)

这无疑是一种浪费

做法

\(D_i + c_{ij}\ge D_j~\Leftrightarrow~D_i-D_j+c_{ij}\ge 0~~\)①

\(D_i + c_{ij}= D_j~\Leftrightarrow~D_i-D_j+c_{ij}= 0~~\)②

对于一个顶标\(D\),我们可以不断的dfs找\(D_i-D_j+c_{ij}=0\)的增广路经

假设我们当前dfs失败

即使失败还是有一些点能满足\(D_i-D_j+c_{ij}=0\)的

这些点被我们当前dfs到了

我们记这些点的点集为\(V\)

找到\(\Delta= \min\left\{D_i-D_j+c_{ij} \right\} ~|~~ i \in V, j \notin V, flow_{~ij} > 0\)

然后我们对\(~~\forall i\in V ,~~D_i^{\pi}=D_i-\Delta\)

条件①②均没有被破坏

证明:

弧\((i,j)\)可以分成四类,再根据当前dfs失败的条件,有:

\[\begin{aligned}
i\in V,j\notin V &原来D_i-D_j+c_{ij} \ge \Delta> 0&新图 D_i^{\pi}-D_j+c_{ij}\ge 0\\
i\in V,j\in V &原来D_i-D_j+c_{ij} =0&新图 D_i^{\pi}-D_j^{\pi}+c_{ij}= 0\\
i\notin V,j\notin V &原来D_i-D_j+c_{ij}\ge 0&新图 D_i-D_j+c_{ij}\ge 0\\
i\notin V,j\in V &原来D_i-D_j+c_{ij} \ge 0&新图 D_i-D_j^{\pi}+c_{ij}\ge \Delta\\
\end{aligned}
\]

可以发现第一类弧中一定有至少一条满足

\(原来D_i-D_j+c_{ij}=\Delta~~~~~~~新图 D_i^{\pi}-D_j+c_{ij}=0\)的

即至少有一条新的边进入了 \(D_j = D_i + c_{ij}\) 的子图

可以发现一条增广路的流量为 -D[S]

实现

struct ZKW{
int flow,cost;
int D[M],V[M]; int aug(int x,int fl){
V[x]=1;
if(x==T) return cost+=-D[S]*fl, flow+=fl, fl;
int p,y,tp;
for(p=e(x);p;p=e[p].nxt)
if(e[p].f && !V[y=e[p].y] && D[x]+e[p].d-D[y]==0)
if(tp=aug(y,min(fl,e[p].f))) return e[p].f-=tp, e[p^1].f+=tp, tp;
return 0;
} bool mdf(){
if(V[T]==1) return 1;
int i,x,y,z=INF;
for(i=2;i<=e.te;i++)
if(e[i].f&&V[x=e[i^1].y]&&!V[y=e[i].y]) z=min(z,D[x]+e[i].d-D[y]);
if(z==INF) return 0;
for(i=0;i<=T;i++) if(V[i]) D[i]-=z;
return 1;
} void solve(int ned){
flow=0, cost=0;
memset(D,0,sizeof D);
do memset(V,0,sizeof V),aug(S,INF); while(mdf());
if(flow==ned) printf("%d\n",cost);
else puts("impossible");
}
}zkw;

zkw费用流 学习笔记的更多相关文章

  1. 学习了ZKW费用流

    所谓ZKW费用流,其实就是Dinic. 若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2) 然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^ ...

  2. 图论-zkw费用流

    图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...

  3. zkw费用流+当前弧优化

    zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...

  4. zkw费用流

    期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...

  5. 【zkw费用流】[网络流24题]餐巾计划问题

    题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...

  6. zkw线段树学习笔记

    zkw线段树学习笔记 今天模拟赛线段树被卡常了,由于我自带常数 \(buff\),所以学了下zkw线段树. 平常的线段树无论是修改还是查询,都是从根开始递归找到区间的,而zkw线段树直接从叶子结点开始 ...

  7. CSU 1948: 超级管理员(普通费用流&&zkw费用流)

    Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...

  8. BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流

    https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...

  9. P4015 运输问题【zkw费用流】

    输入输出样例 输入 #1复制 2 3 220 280 170 120 210 77 39 105 150 186 122 输出 #1复制 48500 69140zuixiaofeiyo 说明/提示 1 ...

随机推荐

  1. Scrum立会报告+燃尽图(十月十三日总第四次):前期宣传相关工作

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2194 Scrum立会master:刘欣 一.小组介绍 组长:付佳 组员: ...

  2. jdbc 5.0

    1.事务 事务将单个SQL语句或一组SQL语句视为一个逻辑单元,如果任何语句失败,整个事务将失败. jdbc的MySQL驱动程序中的事务默认是自动提交. 默认情况下,每个SQL语句在完成后都会提交到数 ...

  3. 【Leetcode】113Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...

  4. saltstack基础篇

    使用saltstack的前提是PPT      服务.流程.工具和技术 安装 rpm -Uvh http://mirrors.yun-idc.com/epel/6Server/x86_64/epel- ...

  5. excel表中判断A列与B列内容是否相同,相同的话在C列按条件输出!

    判断两列数据是否相同,有以下几个函数判断(做笔记于此,方便以后查找): 1.=IF(AND(A4=B4),"相同","") 在C列输出相同字符 2.=IF(A1 ...

  6. 第209天:jQuery运动框架封装(二)

    运动框架 一.函数------单物体运动框架封装 1.基于时间的运动原理 动画时间进程 动画距离进程 图解: 物体从0移动到400 当物体移动到200的时候 走了50% 同样的,物体总共运行需要4秒 ...

  7. 【.Net】从字符串数组中寻找数字的元素

    那是写一个类别来处理数字元素并收集起来. 开发程序,解决方法不是唯一的.相同的功能实现,方法不止一个. 参考下面代码: class Ak { private string[] _stringArray ...

  8. SPOJ3899——Finding Fractions

    SPOJ上的每个题目都做得我泪牛满面. 这个题目也是的.题目意思是给你两个分数a/b和c/d,要你求出一个分数p/q,使得a/b<p/q<c/d,且p最小. 看完题目后半天都没有任何思路哦 ...

  9. 【Java并发编程】之二:线程中断

    [Java并发编程]之二:线程中断 使用interrupt()中断线程 ​ 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一 ...

  10. 【数据库_Mysql】MySQL—修改表时给表添加联合主键约束

      添加语法如下: “ALTER TABLE table_name ADD CONSTRAINT pk_table_name PRIMARY KEY(列名1,列名2):” [示例1]假设订房信息表(O ...