• 单源最短路径基础算法总结 INnoVation


    image-20220602235607401

    N:端点数 M:边数

    1.Dijkstra

    dist[1] = 0, dist[i] = +∞
    for i ← 1 to n
    	t ← 不在s中的距离最近的点
    	s ← t
    	用t更新其他点的距离
    

    时间复杂度分析

    dist[1] = 0, dist[i] = +∞
    for i ← 1 to n
    	t ← 不在s中的距离最近的点  O(n^2)
      s ← t  n次
      用t更新其他点的距离	m次
    

    朴素版的时间复杂度是\(O(n^2)\)

    dist[1] = 0, dist[i] = +∞
    for i ← 1 to n
    	t ← 不在s中的距离最近的点  O(1)
      s ← t  n次
      用t更新其他点的距离	m * log^n
    

    堆优化版时间复杂度是\(mlog^n\)

    Q:为什么处理不了负数

    因为Dijkstra每轮都要确定一个端点的最终最短路径,而如果存在负权边,那路径可能是需要拐弯的

    比如,有以下边,由A出发,求A -> C的最短路

    A -> B: 4
    A -> C: 5
    B -> C: -1
    

    Dijkstra求出结果必然是 A -> C: 5,而实际结果是 A -> B -> C: 3

    Q: 为什么边权都是正数时,不存在此问题

    边权都是正数时,所有端点的最短路都是对着走到路径的增多不断增大的,因此不存在绕路走反而更近的情况,因此不存在此问题

    2.Bellman-Ford

    BF算法执行k轮的含义: 经过不超过K条边到达其他点的最短距离

    存储下所有边M
    置所有点的距离为无穷,dis[1] = 0
    
    - 每轮循环尝试所有边,看能否对dis数组进行更新
    - 如果有N条边,那么理论上更新N - 1次就能得到所有
    

    3.SPFA

    在Bellman-Ford基础上改进,Bellman_Ford每轮尝试使用所有边进行更新,而SPFA只使用上一轮更新过的点进行向后更新。
    

    4.求负权回路

    方法一 Bellman-Ford

    BF算法执行k次的意思是,经过不超过K条边,到达其他点的最短距离,因此理论上说,假设图有N个点,那么执行N - 1轮,dis存储的就是所有的点的最短路,如果此时dis在执行一轮,仍然可以更新,那么就必然存在

    方法二 SPFA

    在SPFA基础上,设置一个cnt数组,存储每个点被更新的次数,理论上任意一个点被更新次数最多就是N-1,如果更新次数≥N,那必然是存在负权回路

  • 相关阅读:
    Javascript之DOM的三大节点及部分用法
    Javascript之全局变量和局部变量部分讲解
    《TCP/IP详解 卷1:协议》系列分享专栏
    说一说MySQL的锁机制
    《TCP/IP详解 卷1:协议》第3章 IP:网际协议
    PHP连接MySql闪断自动重连的方法
    关于MySQL的锁机制详解
    React 源码中的依赖注入方法
    《Mysql高级知识》系列分享专栏
    《AngularJS学习整理》系列分享专栏
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/16672143.html
Copyright © 2020-2023  润新知