【算法】网络延迟时间 (Dijkstra)

题目

有 n 个网络节点,标记为 1 到 n。

给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。

现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。

示例 1:
在这里插入图片描述

输入: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 <= ui, vi <= n
  • ui != vi
  • 0 <= wi <= 100
  • 所有 (ui, vi) 对都 互不相同(即,不含重复边)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/network-delay-time

Dijkstra解法

解题思路

  • 题目实际是求节点K到其他所有点中最远的距离,所以首先求出节点K到其他所有点的最短路,然后取最大值即可

  • Dijkstra算法:

    1. 核心思路就是贪心,从所有未确定最短路的点中,找到距离K点最近的点x

      int x = -1;
      for (int j = 0; j < n; j++) {
          if (!used[j] && (x == -1 || dist[j] < dist[x])) x = j;
      }
      
    2. 通过点x更新所有点距离K点的最短距离。

      for (int j = 0; j < n; j++) {
      	dist[j] = Math.min(dist[j], dist[x] + map[x][j]);
      }
      
    3. 将点x标记为已经确定最短路。

      used[x] = true;
      
    4. 重复123步骤,直到所有点标记为已确定最短路,循环结束

代码

class Solution {
    
    
    public int networkDelayTime(int[][] times, int n, int k) {
    
    
        final int INF = Integer.MAX_VALUE / 2;
        if (times.length == 0) return - 1;
        
        // 邻接矩阵存储边信息
        int[][] map = new int[n][n];
        for (int i = 0; i < n; i++) {
    
    
            Arrays.fill(map[i], INF);
        }
        for (int[] time : times) {
    
    
            int i = time[0] - 1;
            int j = time[1] - 1;
            map[i][j] = time[2];
        }
		
        // 使用dijsktra计算k点到其他所有点的最短距离,并返回为int[]
        int[] dist = dijkstra(map, n, k);
		
        // 找到距离最远的点
        int res = Arrays.stream(dist).max().getAsInt();
        return res == INF ? -1 : res;
    }

    public int[] dijkstra(int[][] map, int n, int k) {
    
    
        final int INF = Integer.MAX_VALUE / 2;
        // 从源点到某点的距离数组
        int[] dist = new int[n];
        Arrays.fill(dist, INF);
        // 由于从 k 开始,所以该点距离设为 0,也即源点
        dist[k - 1] = 0;
		
        // 节点是否被更新数组
        boolean[] used = new boolean[n];

        for (int i = 0; i < n; i++) {
    
    
            // 在还未确定最短路的点中,寻找距离最小的点
            int cur = -1;
            for (int j = 0; j < n; j++) {
    
    
                if (!used[j] && (cur == -1 || dist[j] < dist[cur])) cur = j;
            }
			
            // 用该点更新所有其他点的距离
            used[cur] = true;
            for (int j = 0; j < n; j++) {
    
    
                dist[j] = Math.min(dist[j], dist[cur] + map[cur][j]);
            }
        }

        return dist;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45177370/article/details/120631209