图论进阶总结 【第一部分 最短路和最小生成树】

图论进阶总结 【第一部分 最短路和最小生成树】

1.最短路

最短路其实是一个约束系统,这不太明显。但是我们要求一条最短的路径,首先思考如果可以将dist[x]更新dist[y],显然要dist[y]dist[x]+edge(xy)dist[y]\ge dist[x]+edge(x\to y) ,那么只要使得所有的这种更新都进行完毕,就求出了最短路,即对于所有边都满足dist[y]dist[x]+edge(xy)dist[y]\le dist[x]+edge(x\to y)

好像这种方法关联了很多,因为这是一种”迭代“的思路,一种渐渐逼近目标的方法。

这是不同于递推的,递推只会有序地推一次。所以递推会快但是解决的问题会少。

所以联系到后面的差分约束,我们也发现这种迭代更加适合处理复杂的命题逻辑以及传递关系。

1.1 求解

对比

算法 Dijkstra Dijkstra-Heap Bellman-Ford SPFA Floyd
时间复杂度 O(N2)\operatorname O(N^2) O(MlogN)\operatorname O(M \log N) O(NM)\operatorname O(NM) O(kM)\operatorname O(kM)(不稳定,但我认为不是错的) O(N3)\operatorname O(N^3)
思想 贪心选点 贪心选点/堆优化 迭代/松弛 迭代/队列优化避免无效扫描 动态规划

注:其中Floyd当然是全源最短路算法;其实我不很理解为什么有人喜欢在不论前提的情况下反对SPFA,因为它实际上在负权图上是现阶段最好的解决方案。否则你可能喜欢一篇论文,里面提了一个O(mlog2(n)log(nW)loglogn)\operatorname O(m \log^2(n) \log (nW)\log \log n) 还能处理负权的SSSP。

一些补充

  • Dijkstra与它的贪心

《算法竞赛进阶指南》的初版上有一个错误:在最短路这一节的“最优贸易”这道题中,用于求从起点到达一个点经过的所有路径上点权最小/大的点时,lyd本写了Dijkstra,后来修订又把它改掉了。

所以为什么Dijkstra不可以处理这样的东西呢?

Dijkstra不会被卡、快于SPFA的基本原因是它采用贪心策略直接避免了重复更新,保证从堆中取出的时候就是最优的。但是这个问题有没有这样的性质?

没有,这是求一个路径上最值,并不是全局和最优,这就是说,在SSSP问题中当前已确定集合的“下一阶段点”中距离最小的点的最短路肯定确定,因为在非负权图上再绕一定不可能得到更优的答案了。但是路径最值就不一定了,后面的点权即使非负,你也不能保证他们带来的最后答案的变化是单调的。

有得必有失。什么都一样。

  • Floyd的动规

当然,原先Floyd的状态设计有必要一提:F[i][j][k]F[i][j][k] 表示,经过前k个点从i到j的最短路。

后来把k压掉了。但是这并不妨碍它成为阶段,必须放在最外层循环。

  • SPFA:再算一遍

考虑SPFA发现点还能更新的过程:一旦又被更新,无论它之前有没有拿来扩展别的点,都要重新入队,再次尝试更新。

这就是SPFA可以处理复杂问题的逻辑。很遗憾,这也导致了它容易被卡这个问题。

鱼和熊掌不可得兼。追求平衡与适用才是最好选择。

2.最小生成树

最小生成树有一个比较重要的性质:最小生成树一定包含图中边权最小的边。

这可以使用反证法证明。他的意义是,我们可以根据这个对最小生成树进行变换。

算法过程继续跳过,只是对比以下:

算法 Kruskal Prim
时间复杂度 O(mlogm)\operatorname O(m \log m) O(n2)\operatorname O(n^2) 优化后 O(mlogn)\operatorname O(m \log n)
思想 贪心选边/并查集维护连通性 贪心选点/堆优化

3.例题

前述DP章节也提到了这道题,上面1部分的论述讨论了递推与迭代。本题如果使用DP,会带有后效性,使用迭代的方法就可以计算这个结果。

作为图论的角度理解,这个题目由于需要保存已经使用的免费次数,所以将每一个节点拆成k个来”扩展一维状态“。在这种图上求最短路,称其为分层图最短路

显然若A<B and B<C则A<C,这就是传递性。

传递闭包又是Floyd算法的一大应用,其目的是通过现有关系尽可能运用传递性推出更多的关系。

可以发现,N是特别大的,但是T是很小的。

所以考虑先求出最短路然后再在最短的一条边上来回移动。这是贪心。

当然,这题DP意味是浓重的,如果获得了从i->k经过p条的最短路和从k->j经过q条的最短路

那么就可以获得从i->j经过p+q条的最短路。如何合并呢?考虑枚举矩阵里的内容然后取min。然后又注意到如果合并经过p条和经过q条的矩阵得到p+q,那么矩阵快速幂就显而易见了。

只要有某种方法合并两个矩阵使得阶段信息是这种“和/积变换”的,都可以矩阵快速幂优化。

Kruskal算法的思想即贪心,如果题目需要求满足特殊条件的MST,不妨先满足条件,再贪心地进行调整。

本题不是求特殊的MST,但是要求由MST生成完全图,所以只需要简单地保证MST上边的最小性即可。

求的是最小路径生成树。由近到远依次考虑每一个点,看看有哪些点满足连接条件。

这种要求点满足特殊关系的生成树问题,可以考虑按照Prim的思路去选点求。

注意到如果一条边(u,v)不在从u到n的最短路径上的话就会被警告,然后可以将这条边的边权转化为走这条边受到警告的次数。

可是如果求每个u->n的最短路径耗时太长,对于终点比较少的这种问题,建立反图可以将终点化起点。

posted @   haozexu  阅读(66)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示