您的位置:首页 > 理论基础 > 计算机网络

网络流小结

2015-11-11 22:42 363 查看
对这段时间做的网络流问题做一个小结,希望有用,题目的话,可以去我的专题里面找

网络流算法的模版和详解

EK算法

ISAP

Dinic

MCMF

论文和知识点的讲解

胡伯涛:算法合集之《最小割模型在信息学竞赛中的应用》

模型和建模

1.多源多汇问题:源有多个,汇也有多个,流可以从任意一个源流出,最终可以流向任意一个汇,总流量等于所有源流出的总流量,也等于流进所有汇的总流量

建模方式:加一个超级源s’和超级汇t’,然后从s’向每个源引出一条有向弧,容量为无穷大,每个汇向t’引一条有向弧,容量为无穷大

题目:UVA-11045

2.结点容量:每个结点都有一个允许通过的最大流量,称为结点容量

建模方式:把每个原始结点u分裂成u1和u2两个结点,中间连一条有向弧,容量等于u的结点容量。原先到达u的弧改成到达u1,而原先从u出发的弧改成从u2出发

题目:UVA-10330

3.无源无汇的有上下界的流

模型分析:这个模型比较特别,没源又没汇,而且每条弧除了有容量c之外,还多了一个下界b。

那就分析一下该模型的特点,既然无源无汇,那么每个结点就都要满足”入流=出流”这个流量平衡条件

依此性质,就求出每个点的入流和出流,用d[]代表每个结点的入流-出流。接着设置一个超级源点S和一个超级汇点T,因为要满足所有结点的入流=出流,所以:

1.d[u] > 0的点,建立 (S->u)的边,容量为d[u]

2.d[u] < 0的点,建立(u->T)的边,容量为-d[u]

3.所给的边(u,v,c,b),建立(u->v)的边,容量为c - b,为什么是c - b,因为我们假设改边已经流了b的流量了

如果求出来的是满流,表示能满足每条边的下界

解释一下为什么,根据流量守恒的性质,所有点的入流=所有点的出流,所以满流的时候,就满足了。

为什么要这样建模,首先,d[u]>0的连向了源点,也就是说,从u出发的都是出流了,只要该边满流了,就能让u点的入流=出流了

d[u] < 0的情况相同

题目:SGU-194

4.有源有汇的有上下界的最大流

模型分析:这个和第二个就有区别了,因为有源有汇了,但是不同之中还是有相同的,就是有上下界,那么能否按照无源无汇有上下界的的思路呢?

答案是可以的,但是跑出来的却是无源无汇的结果,但是这题是有源有汇的,所以这里要加一条边,假设源点为s1,汇点为t1,加的这条边就是t1 - > s1,容量为无穷大

为什么要加上这条边呢?因为有了源点和汇点,而源点和汇点又都是特殊的点,一个是只出不入,一个是只入不出的,所以d[t1]必然是大于等于0的,而d[s1]是小于等于0的。而当(t1->s1)这条边有流时,就相当于从源s1流出了流量了,所以这条流是条可行流

在附加了该边之后,建模方式还是按照上面那样,设置超级源点S和超级汇点T,按情况连接向那些入流-出流的点,如果满流了,表示能满足下界了,但是满足下界了,不代表就是最大流了,所以我们还得在残余网络上,去掉超级源点和超级汇点,再跑一次从(s1->t1)的最大流,该最大流加上(t1->s1)的那条边的流,就是所要的最大流了

题目:ZOJ-3229

5.有源有汇的有上下界的最小流

建模分析:这个和上面的情况又不同了,这次是要最小流,要在最小流的情况下,又要满足下界的限制,所以处理起来就比较麻烦了,但也不是很麻烦

对比上次的模型,上次是添加了一条(t1->s1)的边,这条边流过的流量是可行流。所以,这里也要添加,但添加的顺序不一样

首先,还是处理出所有的结点的入流-出流,然后连向超级源点S,超级汇点T,和无源无汇的那种情况相同,把源汇当成普通结点,先跑出最大流了,再添加边,再跑一次最大流,接着得到的(t1->s1)流就是所求的最小流了

这里解释一下为什么,首先,我们在不添加(t1-s1)的情况下,先跑了一次(S到T的)最大流,表示的是不提供流量的情况下,让那些能平衡流量结点的尽量去平衡,这样就能减少流量了

接着添加了(t1-s1)了,再跑一次(S到T的最大流)的话,相当于是提供了流量了,在提供了流量的情况下,如果能满流,即满足所有边的下界的话,就表示找到可行流了

为什么是最小的,因为第一次已经将那些能平衡的尽量平衡了,不能平衡的,就需要流了,所以,这是在实在不能平衡的情况下,才给流的,所以这是最小流

题目:SGU-176

6.行列模型 :给你一个矩阵,然后给出一些行的和,和一些列的和,现在问这个矩阵的上面的数字

建模方式:矩阵上的一个数字,即属于某一行,也属于某一列,发现该性质后,就可以建图了

首先设置一个超级源点S和超级汇点T

超级源点S和给出的每一行相连,容量为该行的和

超级汇点T和给出的每一列相连,容量为该列的和

接着就是矩阵上的每个数字了,找到该数字的行和列,并相连,容量为所给矩阵数字最大值

就这样,跑最大流,得到的边上的流量就是该数字的值了

不过这里得注意,因为边的流量有可能是0,所以容量还是得依题目而变,有的题目要求的是矩阵上面的数字不能为0的,最小要为1的,这个也好办,给相应的边的容量减去相应的最小值就可以了

比如,最小值要求是1,那么超级源点S到每行的容量就变成该行的和-(该行的数的数量),列也一样,而每个数字连向行列的容量也要相应的减去1,因为现在我们将0看成1,1看成了2了,所以要相应的变化

题目:HDU-3338

UVA-11082

7.时序模型:给出起点和终点,再给出一系列的边,连边有相应的限制,就是时间限制,如果在时间限制内可行,那就可以连边,最后问最大流

建模分析:找到可连的边连接起来就可以… 这种模型我见的也不多

题目:UVA-1161

8.层次模型:慢慢的增加边,直到达到要求为止

建模分析:我也不知道该怎么取名字,反正就是慢慢的枚举,一层一层的加边,直到得到所需的流为止

题目:UVALIVE-2957

HDU-1733

9.费用与流量平方成正比的最小流:容量c均为整数,并且每条弧还有一个费用系数a,表示该弧流量为x时费用为ax^2,问最小费用最大流

建模分析:观察式子,当流量为1时,费用为a * x,流量为2时,费用为a * x^2,流量为3时,费用为a * x ^ 3

随着流量的增加,可得费用的增长规律,1 * x ^ 2, 3 * x ^ 2,5 * x ^ 2,

所以建变的时候,可以将一条边拆成n条边,容量都为1,费用分别为x * 2, 3 * x ^ 2, 5 * x ^ 2,这样,就满足费用为a * x ^ 2了

题目:UVALIVE-5095

接下来的模型都要考虑到最小割的性质了

可参考该论文胡伯涛:算法合集之《最小割模型在信息学竞赛中的应用》

里面有详细的证明和建图方式,下面我就不详说了,具体自己去看,自己理解

10.分数规划

建图方式:因为式子要满足w - g * c,所以枚举g,边的容量变成w - g * c

当h(g) > 0时,表明g偏小

h(g) < 0时,表明g偏大

题目:ZOJ-2676

11.最大权闭合

建模分析:找出所有的点权为正的,这些点和超级源点S相连接,容量为该点的点权

所有点权为负的,和汇点T连接,容量为点权的绝对值

所给的边,相连,容量为INF

然后用sum(正点权) - 最小割就是最大权闭合了

题目:HDU-3061

POJ-2987

12.最大密度子图

建模分析:最大密度子图要满足h(g) = (U * n - Mincut ) / 2 = 0,即要满足分数规划的要求,当h(g) > 0 时,表示g < g*,所以g要增大

当h(g) < 0时,表示g > g*,g要减小

当h(g) = 0时,刚好

上面的u表示的是为了防止点权变成负数而加上去的正数,因为有n个点加上了那个数

选择一个点的代价是2 * g - d,d表示的是该点的度数

1.点权和边权为1的最大密度子图

这个比较好办,按照上面所给的式子建图

超级源点S和所有点连接,权值为m

超级汇点T和所有点连接,权值为m + 2 * g - d

有边权的边相连,容量为1

2.点权为1,边权不为1的最大密度子图

只需要修改所给边的边权即可,将其修改成所给边权

3.点权和边权都不为1

这时候,选择一个点的代价就变成了2 * (g - 该点的点权) - d了

为了防止点权变成负数,所以要加上U = 2 * sum(点权) + m

超级源点S和所有点相连接,权值为U

超级汇点T和所有点相连接,容量为U + 2 * (g - 该点的点权) - d

有边权的相连接,容量为所给的边权

h(g) 的U也要相应改变

题目:UVALIVE-3709

13.二分图最小权点覆盖

模型分析:所给的匹配边,只能有一个在点集内,最小割刚好符合

X集合的点和超级源点S连接,容量为该点的点权

Y集合的点和超级汇点T连接,容量为该点的点权

所给的边连接,容量为无穷大

所得到的最小割就是最小点权覆盖了

14.二分图最大权独立

模型分析:因为二分图的最小点权覆盖和二分图的最大权独立是对偶的

所以只要用总权值-二分图最小点权覆盖即可

15.混合欧拉回路

混合图的欧拉回路,借用别人的吧

混合图欧拉回路用的是网络流。

把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路。

现在每个点入度和出度之差均为偶数。将这个偶数除以2,得x。即是说,对于每一个点,只要将x条边反向(入>出就是变入,出>入就是变出),就能保证出 = 入。如果每个点都是出 = 入,那么很明显,该图就存在欧拉回路。

现在的问题就变成了:该改变哪些边,可以让每个点出 = 入?构造网络流模型。有向边不能改变方向,直接删掉。开始已定向的无向边,定的是什么向,就把网络构建成什么样,边长容量上限1。另新建s和t。对于入 > 出的点u,连接边(u, t)、容量为x,对于出 > 入的点v,连接边(s, v),容量为x(注意对不同的点x不同。当初由于不小心,在这里错了好几次)。之后,察看是否有满流的分配。有就是能有欧拉回路,没有就是没有。查看流值分配,将所有流量非 0(上限是1,流值不是0就是1)的边反向,就能得到每点入度 = 出度的欧拉图。

由于是满流,所以每个入 > 出的点,都有x条边进来,将这些进来的边反向,OK,入 = 出了。对于出 > 入的点亦然。那么,没和s、t连接的点怎么办?和s连接的条件是出 > 入,和t连接的条件是入 > 出,那么这个既没和s也没和t连接的点,自然早在开始就已经满足入 = 出了。那么在网络流过程中,这些点属于“中间点”。我们知道中间点流量不允许有累积的,这样,进去多少就出来多少,反向之后,自然仍保持平衡。

题目:poj-1637
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: