网络流
最大流
费用流
无源汇上下界可行流
这里先要介绍一下流量平衡这个概念:在一个合法的无源汇网络流中,每个点的流入量等于流出量。如果是有源汇的网络流,把源点和汇点看做一个点也是满足流量平衡的。(十分显然)
那么在无源汇上下界网络流中,首先每条边的下界是我们必须满足的,假设我们把每条边先流满下界。那么每条边只需要满足上界的限制,那么可以加边
a
d
d
(
u
,
v
,
u
p
−
l
o
w
)
add(u,v,up-low)
add(u,v,up−low)(反向边都省了),下面我们要解决的就是流量平衡的问题了。
设
a
[
]
a[]
a[]为一个点的流入量-流出量。
i
f
(
a
[
x
]
>
0
)
if(a[x]>0)
if(a[x]>0)
那么我们需要在新网络上给x增加流出量,所以我们需要有一个点向x流入a[x]的流量让x在原网络上把这些流量流出去了,以此满足流量平衡
i
f
(
a
[
x
]
<
0
)
if(a[x]<0)
if(a[x]<0)
同理我们需要给x增加-a[x]的流入量,所以我们让x向一个点流出-a[x]的流量(也就是从原网络中获取-a[x]的流量)。
那么做法就出来了:增加超级源汇,S向a[x]>0的点
a
d
d
(
S
,
x
,
a
[
x
]
)
add(S,x,a[x])
add(S,x,a[x]),a[x]<0的点向T连
a
d
d
(
x
,
T
,
−
a
[
x
]
)
add(x,T,-a[x])
add(x,T,−a[x])
跑一遍dinic,如果S的所有出边满流,那么T的所有入边也满了(所有a[]的和为0),也就是通过内部调整满足了流量平衡,那么找到一组可行解。
有源汇上下界最大流
我们添加
a
d
d
(
t
,
s
,
i
n
f
)
add(t,s,inf)
add(t,s,inf)那我们成功转换成流无源汇的情况,按照无源汇的方式可以跑出一组可行流,此时我们新加的那条边的反向边的vlu就是s到t的流量sum,我们要尝试着将其扩大。
想想我们无源汇的操作干了什么,我们满足了所有边的的下界跑出一组解,然而残余网络上可能还有一些自由流可以继续贡献,所以我们将S,T的所有连边删掉,把新加的边也删掉,跑一遍s,t最大流,加上sum就是答案。
有源汇上下界最小流
和最大流差不多,到跑出可行解都没有区别,这次我们要尝试将sum减小,也就是尝试从t退尽量多的流回到s,所以只需要将s,t最大流改成t,s最大流,然后sum减去它就是答案。