刷最小费用流的时候看到了循环流的做法,记录一下对最小费用循环流的理解
最小费用流变体:费用为负的情况
如果图中含有负权边,连续最短路算法最初计算势的值时就不能使用 D i j k s t r a Dijkstra Dijkstra 算法,而要改用 B e l l m a n − F o r d Bellman-Ford Bellman−Ford 算法。如果图中出现负圈,可以利用 B e l l m a n − F o r d Bellman-Ford Bellman−Ford 算法找到负圈,并在负圈上尽量增广将其消去。
对于流量 F F F 一定的情况,可以通过变形消去负权边,假设边 e = ( u , v ) e=(u,v) e=(u,v) 权值 d < 0 d<0 d<0
新增源点 S S S 和汇点 T T T,从 S S S 向 s s s 连一条容量为 F F F 费用为 0 0 0 的边,从 t t t 向 T T T 连一条容量为 F F F 费用为 0 0 0 的边;对于负权边 e = ( u , v ) e=(u,v) e=(u,v) 可以让其一开始就已经满流,再从 S S S 向 v v v 连一条容量为 c ( e ) c(e) c(e) 费用为 0 0 0 的边,从 u u u 向 T T T 连一条容量为 c ( e ) c(e) c(e) 费用为 0 0 0 的边
这样变形之后,除去了图中的负权边,原图流量为 F F F 的最小费用流的费用,就等于新图流量为 F + ∑ 负 权 边 e c ( e ) F+\sum_{负权边e} c(e) F+∑负权边ec(e) 的最小费用流的费用加上 ∑ 负 权 边 e c ( e ) × d ( e ) \sum_{负权边e} c(e)\times d(e) ∑负权边ec(e)×d(e)
最小费用循环流
最小费用循环流的费用即图中圈权值和的最小值。从连续最短路算法的观点来看,最小费用流不能求出图中的圈权值,那么利用处理负边权边的思想处理这个问题,即 预先取负权边的边权值(在答案中计入负权边权值),使之形成循环流
对于各负权边,从 S S S 向 v v v 连一条容量为 c ( e ) c(e) c(e) 费用为 0 0 0 的边,从 u u u 向 T T T 连一条容量为 c ( e ) c(e) c(e) 费用为 0 0 0 的边;考虑到图中消去了负圈,则对于同时与 S S S、 T T T 存在连边的点,可以相互抵消。故 对于新增源点 S S S、新增汇点 T T T,其与 u u u、 v v v 的连边容量取决于负权边端点的入流量与流量,若入流量大于出流量,从 S S S 向 v v v 连一条容量为入流量减出流量,费用为 0 0 0 的边;若出流量大于入流量,从 u u u 向 T T T 连一条容量为出流量减入流量,费用为 0 0 0 的边
此前消负权边时,预先使之满流。实际上,满流意味着这条负权边的流量可以回退,即此负权边可以取或不取。若回退流量,意味着取消之前的预取(答案除去此负权边);出现这种情况时,此负权边组成的最小权值圈为正圈,又由于求最小费用流,不取正圈,故将流退回
一般而言,负权边可以取或不取,即预先使之满流,如 UVA 1659;若负权边必须取到,则不预先使之满流,按原图连边,此时可以求正圈最小权值,如 AOJ 2230
如果图中无负边,最小费用循环流无源、汇点建立,结果为 0 0 0,意味着此时不取任一条边费用最小