算法课笔记系列(六)—— 图(Part2)

本文是算法课笔记系列的第六篇,主要探讨图的最短路径问题和网络流。介绍了最短路径动态规划,包括Bellman-Ford算法用于检测负环;所有点对之间的最短路径问题,如Floyd-Warshall和Johnson算法;最后讲解了网络流中的最大流和最小切割问题,以及Ford-Fulkerson算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一周去了一趟说走就走的治疗之旅,所以算法课都没能上。:( 不过,人生有过这样一次,很足够。只要永远做自己认为对的事情就不会有跨不过去的坎。

跟上周一样,这一周的内容包含几个小部分,分别为最短路径动态规划、所有点对之间的最短路径和网络流。

第一部分:最短路径动态规划

对于一个有向图G=(V, E), 每一条边权重为cvw(权重可为负), 问题是找到从节点s到t的最短的路径。如果边的权重中有负值,则Dijkstra方法不适用。因此我们想到一个办法,给每一个权值加上一个正常数使得每一条边的权重都为非负,这个方法也不行。

这里定义一个负(成本)环。如下图所示,顾名思义,所有边的权值的和为负数。

                                  

如果一个从s到t的路径中包含一个负(成本)环,那s-t之间不存在最短路径,否则,存在一个最短路径。如下图。

                             

下面用动态规划来解决最短路径的问题。

定义OPT(i, v) 表示使用最多i条边的最短的v到t的路径P。

1) P中使用最多i-1条边

OPT(i, v) = OPT(i - 1, v)

2) P使用第i条边

如果(v, w)是第一条边,那么OPT使用(v, w), 然后选择最佳的w-t路径使用最多i-1条边

          

通过之前的观察,可以得出,如果没有负环,那么OPT(n - 1, v)为最短的v-t路径的长度。

实现代码如下:

          

时间复杂度为O(mn), 空间复杂度为O(n^2).

下面提出一种改进。

保持一个矩阵M[v]为我们目前能够找到的最短的v-t路径。除非M[v]在前一个迭代中改变了,否则不需要检查(v, w)形成的边。这里有这样一个定理,在整个算法中,M[v]是v-t路径的长度,在i轮更新之后,M[v]不会大于使用不多于i条边的最短路径的长度。内存消耗为O(m+n),时间复杂度为O(mn)最坏情况,但是实际会更快。

Bellman-Ford实现算法如下:

          

使用以上算法可以证明,如果对于所有的v有OPT(n, v) = OPT(n - 1, v),那么就没有负环。

如果OPT(n, v) < OPT(n - 1, v), 那么任何从v到t的最短路径都包含一个环W,并且,W包含负数的权值边。

以上两条可以用于检测负环。Bellman-Ford算法的时间复杂度为O(mn), 空间复杂度为O(m+n).<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值