关于单源最短路的建图方式

1.四种单源最短路算法
  • Dijkstra

    设计思想:dijkstra算法本质上算是贪心的思想,每次在剩余节点中找到离起点最近的节点放到队列中,并用来更新剩下的节点的距离,再将它标记上表示已经找到到它的最短路径,以后不用更新它了。

    分为朴素版与堆优化版本
    朴素版

    • 适用场景:稀疏图且不存在负环。
    • 时间复杂度:O(n^2)。

    堆优化版本

    • 适用场景:稠密图且不存在负环。
    • 时间复杂度:O(nm)。
  • bellman-ford

    设计思想:该算法能够保证每更新一次都能确定一个节点的最短路,但与dijkstra不同的是,并不知道是那个节点的最短路被确定了,只是知道比上次多确定一个,这样进行n-1次更新后所有节点的最短路都确定了(源点的距离本来就是确定的)。
    适用场景:适用于存在负环的图。
    时间复杂度:O(mn)。

  • spfa
    设计思想:是对bellman-ford算法的队列优化。所以spfa的做法就是把每次更新了的点放到队列中记录下来。
    时间复杂度:一般情况下:O(n);最坏情况下:O(nm),即退化为bellman-ford算法。

  • Floyd
    设计思想: Floyd算法是一个经典的动态规划算法。
    适用场景:是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。
    时间复杂度:O(n^3)。


总结:在无负环时,一般选用堆优化版本Dijkstra算法求最短路;存在负环时,适用spfa算法求最短路;求多源最短路时,适用Floyd算法求最短路。


2.单源最短路的建图方式:

在单源最短路问题中,所用算法离不开上述四种。而问题的关键在于将题意进行转换,再利用上述算法求解最短路。
以下是几种在做题过程中碰到的建图方式:

  • 方式1:传信问题:
    • 问题描述:每个信使收到信件后,将信件传递给与他相连的所有信使。问:所有信使都收到信件所需的最少时间。
    • 问题解决:由于不知道终点是哪一个信使,所以在数据范围较小的情况下,可以适用Floyd算法,再求出由信使1到其他信使所需的最大时间。
      而在数据范围较大的情况下,可以使用堆优化版本的Dijkstra算法,其总时间复杂度为O(n^2log(m))
  • 方式2:求最长距离
    • 问题解决:可以使用堆优化版本的Dijkstra算法,不过需要使用最大堆。
  • 方式3:求最小换乘次数
    • 问题描述:有m条巴士线路。问从A到B最少需要换乘几次。
    • 问题解决:将一条巴士线路上各个城市之间的距离设置为1,这样就可以转换成为最小路径问题
  • 方式4:聘礼问题(多种选择问题)
    • 问题描述:国王需要x1元聘金或y1元+z1物品或y2元+z2物品;而其他物品的主人需要xn元或yn元+yn物品;问最少需要花费多少钱。
    • 问题解决:需要建立一个虚拟源点,用来表示所连接结点,直接购买所需的费用。问题转化为从虚拟源点到国王结点所需的最小费用。
posted @ 2021-03-06 20:42  z_thorn  阅读(116)  评论(0编辑  收藏  举报