LeetCode743网络延迟时间-----迪杰斯特拉算法

题目表述

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

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

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

Disjkstra算法

  1. 使用邻接矩阵graph存储图的信息,graph[i][j]代表i到j的边的权重。
  2. 将将邻接矩阵graph中值初始化为INF,并根据给定的矩阵信息更新邻接矩阵中的值。
  3. 创建一个distance数组,代表源节点到各节点之间的距离,并初始化为INF,其中源节点到其本身初始化为0;
  4. 创建一个访问数组visited,代表已经访问过的节点。
  5. 每次从distance数组中选择距离最短的节点进行更新,并将该节点标记已访问。
class Solution {
 static final int INF = 0x3f3f3f3f;
public static int networkDelayTime(int[][] times, int n, int k) {
    int res = -1;
    int[][] graph = new int[n][n]; // 新建邻接矩阵
    for(int[] tmp : graph){
        Arrays.fill(tmp, INF); // 将邻接矩阵中的值初始化为最大值
    }
    for(int[] tmp : times){
        graph[tmp[0] - 1][tmp[1] - 1] = tmp[2]; // 根据已有矩阵信息更新邻接矩阵
    }
    int[] distance = new int[n]; // 新建距离数组
    Arrays.fill(distance, INF); // 将距离数组初始化为最大值
    distance[k-1] = 0; //源节点到其本身的距离为0
    boolean[] visited = new boolean[n]; // 新建访问数组
    dijkstra(graph, visited,distance, n); // 迪杰斯特拉算法迭代计算源节点到各节点最短路径
    for (int tmp : distance){
        res = Math.max(res,tmp);
    }
    return res == INF? -1 : res;
}
public static void dijkstra(int[][] graph, boolean[] visited, int[] distance,int n){
    for(int i = 0; i < n; i++){ // 迭代,每次寻找最短路径进行更新
        int minIndex = 0;
        int minDis = INF; // minDis代表最短距离, minIndex代表最短距离所对应的下标
        for(int j = 0; j < n; j++){// 在distance数组中寻找最短路径
            if(!visited[j] && distance[j] < minDis){
                minDis = distance[j];
                minIndex = j;
            }
        }
        visited[minIndex] = true;
        for(int k = 0; k < n;k++){ // 更新路径
            distance[k] = Math.min(distance[k], distance[minIndex] + graph[minIndex][k]);
        }
    }
}
}

代码优化(小顶堆)

将源节点到各节点距离和节点编号存入小顶堆中,按距离排序,这样每次取出的都是距离最短的节点。

public static int networkDelayTime(int[][] times, int n, int k) {
        List<int[]>[] g = new List[n];
        for(int i = 0; i < n;i++){
            g[i] = new ArrayList<>();
        }
        for(int[] t : times){
            g[t[0]-1].add(new int[]{t[1]-1, t[2]});
        }
        int[] dist = new int[n];
        Arrays.fill(dist,INF);
        dist[k - 1] = 0;
        PriorityQueue<int[]> que = new PriorityQueue<>((a,b) ->{
           return a[0] != b[0]? a[0] - b[0] : a[1] - b[1];
        });
        que.offer(new int[]{0,k-1});
        while(!que.isEmpty()){
            int[] p = que.poll();
            int time = p[0], x = p[1];
            if(time > dist[x]){
                continue;
            }
            for(int[] e: g[x]){
                int y = e[0];
                int d = e[1] + time;
                if(d < dist[y]){
                    dist[y] = d;
                    que.offer(new int[]{d, y});
                }
            }
        }
        int ans = Arrays.stream(dist).max().getAsInt();
        return ans == INF? -1 : ans;
}
posted @ 2022-04-12 10:43  YoungerWb  阅读(125)  评论(0编辑  收藏  举报