网络流的基本性质与算法

我决定继续我的学术+数学风格,这种风格虽然有点难理解,但是定义精确,而且往往能反映出更多的性质,比语言描述往往更为简洁。

好吧,我们继续我们的网络流的介绍。考虑一个有向图 G=(V,E) ,其源点为 s ,汇点为t,网络流实际上可以用水流类比,比如说在 s 点出发很多(可以理解为无限多)的流量,容易发现,由于每条边实际上都应当有一个流量限制(类比一下生活:水管都有最大通过量),所以到t点的流量实际上有一个上限,而不是无穷大。那么,网络流中的最大流就是来求出这样的上限的。
如果再考虑另一个例子,比如说现在我们有无限多的货物要通过一个公路系统,公路系统上没一条路都有一个容量限制,同时还有收费站,每一吨货物都要收费若干元(而且每一条路上的费用不一定相同),那么同样,我们也只能从起点 s 运一些货物到终点t,而不是无穷多。那么,现在的问题就是,在运的货物最多的情况下,怎样使得所花费的费用最少?那么这就是最小费用最大流了。
用神奇的数学方法描述成线性规划形式,就是像下面这样:

Maximizexta11x1+a12x2+a1nc1a21x1+a22x2+a2nc2am1x1+am2x2+amncm

其中, ci 表示第 i 条边的最大流量,那么这个模型就很容易被看出了。
从上面这一大块式子可以看出一个流的三个特性:

  • 流量平衡:(i,v)Ef(u,i)=(u,i)Ef(i,v)
    • 容量限制: f(i,j)c(i,j)
    • 反对称性: f(i,j) = -f(j,i)

      上述的三个特性都很好理解。比如对于流量平衡,就是对于一个点而言,进去多少流量,也出来多少流量。而容量限制前面已经提到过,就是某一条边上流过的流量不应超过其的最大流量,反对称性这一条件则有点数学的味道,就像“减去 5 ”等价于“加上5”一样,就是定义了一种负流量的概念,也就是流过去多少流量,等价于留回来负的流量,这和流量平衡条件结合一下就很好理解了。

    • 好的,那么最大流怎么求?证明在这里略去,反正我们先上算法。首先是一个定理,以帮助我们理解。倘若我们现在有一个有向图 G={V,E} ,然后定义 f(u,v) 表示边 (u,v)E 的流量,另外 s,tV 分别是整个图的起点和终点,那么,我们便有了一个神奇的定理:


      • 不断增广 st 最短路(也就是使得这条路上通过的流量尽量大),那么最多只需要 O(|V||E|) 次迭代就可以求出最大流。
        关于这个定理的实现有很多。比如说,我们如果直接用BFS/DFS求最短路,然后再直接增广,那么容易考虑到其时间复杂度为 O(nm2) ,也就是Ford-Fulkerson算法。
        当然,F-F算法还有一个要点,就是反向边。考虑一种“撤销”操作,令得流过去的流可以在某种意义上“流回来”,这样才正确。如果没有的话,那么算法就会“一条路走到黑”,陷入局部困境。
        那么,有什么优化的方法吗?Ford-Fulkerson的时间复杂度太高了,有什么方法优化么?有!
        考虑到Ford-Fulkerson有一个瓶颈实际上在求最短路上,那么我们可以先构造一种叫层次图的东西,使得所有的s-t路径都是s-t最短路,那么我们就只需增广这个层次图中每一条路径所对应的边,然后再不断重构层次图就好了。
        考虑这样一种层次图的构建方法,也就是设 h(i) 为点 i 到源点s的最短距离,然后只增广满足 h(v)=h(u)+1 条件的边 (u,v)E 就好了。
        在考虑一下这样做的时间复杂度。每一次的增广,距离至少增加 1 ,然后距离最大为n1,而一共需 O(nm) 次的迭代,于是总共的时间复杂度也就是 O(n2m)
        另外还有更快的做法,无论是在理论时间复杂度上,还是实际上,都各有胜过它的代码。

      但是,Dinic短啊!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值