图论最短路学习笔记(一)Dijkstra算法详解:网络延迟时间

【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】

Dijkstra 算法

  • 可实现:有向图一个点出发到其他点的最短路 (shortest path from one node to other nodes)
    【要求所有边的值 >= 0】
  • 思想:从起点出发,每轮[找到距离起点最近的点cur,更新cur下一节点nxt到起点的距离] × T
  • 拆解:
    • n 个节点,k 为起点,n*n 的graph储存路长(graph[start][end] = val,题目给定不改动)
    • 需要计算并储存的值:
      • 出发点到每个点的距离dist :初始 dist = [inf] * n,dist [k-1] = 0  起点到起点距离=0
                                                (因为题目的k从1开始,index表示要 -1)
      • 每个点是否已找到最短距离done:初始 done = [False] * n
    • 每轮操作:找到 “dist最小 且 done为False” 的点(即本轮要处理的点cur)→ done[cur] = True(表示已找到最短距离)→ 更新cur的下面点nxt【dist[nxt] = min(dist[nxt], dist[cur] + val), val为graph[cur][nxt]】
    • 为什么每轮 “dist最小 且 done为False” 的点cur此时的距离就是最短距离?
      因为 “dist[cur] < dist[node] + val” 一定成立,因为 “dist[node] > dist[cur]”,val表示node到cur的距离 
    • 如何判断该点无法达到: dist[cur] == inf (表示done为False的点里,距离最短为inf,即没有路径可以到达这个点)
    • 如何找到 max(所有点的最短距离) :最后一个“找到最短距离的点cur”  就是所有最短距离中的最大值,因为离出发点越近的点,会先被确定找到最短
  • 模版题:743. 网络延迟时间 - 力扣(LeetCode)
  • 代码1(朴素法):
    class Solution:
        def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
            graph = [[float('inf')]*n for _ in range(n)]
            for u, v, w in times:
                graph[u-1][v-1] = w
            
            dist = [float('inf')]*n
            dist[k-1] = 0
            done = [False]*n
    
            ans = 0
            while True:
                # 找当前距离起点最短且done为False的点
                cur = -1
                for idx, isdone in enumerate(done):
                    if not isdone and (cur < 0 or dist[idx] < dist[cur]):
                        cur = idx
                # 如果所有的点已确定,即 done == [True]*n,返回最后一个答案,即最短距离里面的最大值
                if cur == -1:
                    return ans
                # 如果没有路径可以到达cur,直接返回-1
                if dist[cur] == float('inf'):
                    return -1     
                # 更新ans和到起点距离
                ans = dist[cur]
                done[cur] = True
                for nxt, val in enumerate(graph[cur]):
                    dist[nxt] = min(dist[nxt], dist[cur]+val)
            
            return ans

  • 堆优化方法:用heap来储存待确定最短路径的节点(即 满足“dist[cur]+val < dist[nxt]” 会被放入heap), 不用done列表,但需要比较cur_dist > dist[cur]。
  • 代码2(堆优化):
     
    import heapq
    
    class Solution:
        def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
            graph = [[float('inf')]*n for _ in range(n)]
            for u, v, w in times:
                graph[u-1][v-1] = w
            
            dist = [float('inf')]*n
            dist[k-1] = 0
            
            h = [[0, k-1]]
    
            while h:
                cur_dist, cur = heapq.heappop(h)  # 取最小
    
                if cur_dist > dist[cur]:
                    continue
                
                for nxt, val in enumerate(graph[cur]):
                    if dist[cur]+val < dist[nxt]:
                        dist[nxt] = dist[cur]+val
                        heapq.heappush(h, [dist[nxt], nxt])
                
            ans = max(dist)
            return ans if ans < float('inf') else -1

     

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值