AlgoMooc
你已开通华为OD训练营权益,还差最后一步——完成入营激活(兑换课程 + 加飞书 + 登记服务群),即可解锁全部课程与专属服务。去激活 →
← OD 20 天课程

华为 OD 训练营 · 题解精讲

LeetCode743、网络延迟时间

LeetCode743、网络延迟时间

题目描述

题目链接:https://leetcode.cn/problems/network-delay-time/description/

有 n 个网络节点,标记为 1 到 n。 给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (u(i), v(i), w(i)),其中 u(i) 是源节点,v(i) 是目标节点, w(i) 是一个信号从源节点传递到目标节点的时间。 现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。

示例 1: OiEqbXXdKoEtxCx3gd0cqd3knud.png

输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2 输出:2

示例 2: 输入:times = [[1,2,1]], n = 2, k = 1 输出:1

示例 3: 输入:times = [[1,2,1]], n = 2, k = 2 输出:-1

提示: 1 <= k <= n <= 100 1 <= times.length <= 6000 times[i].length == 3 1 <= u(i), v(i) <= n u(i) != v(i) 0 <= w(i) <= 100 所有 (u(i), v(i)) 对都 互不相同(即,不含重复边)

题目解析

题目要求计算从源点出发到达所有其他节点的最短路径,在所有所有最短路径中找到最大值。 所以这是一个单源最短路问题,可以使用Dijkstra算法来解决,计算出dist数组之后取最大值即可。

Dijkstra算法的具体介绍详见2024/08/17 真题讲解(最短路问题Dijkstra算法专题)

参考代码

参考代码

INF = 100000  # 用于表示一个非常大的数,作为初始的最短距离

class Solution:
    def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
        # 创建一个邻接表,用于存储每个节点的相邻节点及对应的路径权重
        neighbor_dic = defaultdict(list)
        for a, b, w in times:
            # 将边 (a -> b) 和对应的权重 w 加入邻接表
            neighbor_dic[a].append((b, w))  
        
        # 初始化一个列表 dist,用于记录从源节点 k 到每个节点的最短距离
        # 初始时,所有节点的距离都设置为 INF(表示尚未访问或不可达)
        dist = [INF] * (n+1)

        # 初始化一个最小堆,用于在Dijkstra算法中提取当前已知最短路径的节点
        # 堆中元素是 (当前时间, 当前节点) 元组
        heap = [(0, k)]

        # 进行Dijkstra(类似BFS)
        while heap:
            # 从堆中弹出当前时间最小的节点
            cur_time, cur_node = heappop(heap)
            
            # 如果当前节点的已记录最短时间比当前时间更小,说明已经找到更优的路径
            # 因此可以跳过当前节点
            if cur_time > dist[cur_node]:
                continue
            
            # 更新从源节点 k 到当前节点的最短时间
            dist[cur_node] = cur_time
            
            # 遍历当前节点的所有相邻节点
            for next_node, next_weight in neighbor_dic[cur_node]:
                # 计算通过当前节点到达相邻节点所需的时间
                next_time = cur_time + next_weight
                
                # 如果通过当前节点到达相邻节点的时间比之前记录的最短时间更短
                # 则更新相邻节点的最短时间,并将其加入堆中以便进一步探索
                if next_time < dist[next_node]:
                    heappush(heap, (next_time, next_node))
        
        # 找到从源节点 k 到所有节点的最短路径中的最大值
        ans = max(dist[1:])
        
        # 如果最大值小于 INF,说明所有节点都可达,返回最大值作为网络延迟时间
        # 否则返回 -1,表示有节点无法到达
        return ans if ans < INF else -1