Dijkstra 算法

743.网络延迟时间

图片说明

有向+带环+非负权重图+最短路径 【DijKstra】

将所有节点分成两类:
1)已确定从起点到当前点的最短路长度的节点
2)未确定从起点到当前点的最短路长度的节点(下面简称「未确定节点」和「已确定节点」)。

每次从「未确定节点」中取一个与起点距离最短的点,将它归类为「已确定节点」,并用它「更新」从起点到其他所有「未确定节点」的距离。直到所有点都被归类为「已确定节点」。

用节点 AA「更新」节点 BB 的意思是,用起点到节点 AA 的最短路长度加上从节点 AA 到节点 BB 的边的长度,去比较起点到节点 BB 的最短路长度,如果前者小于后者,就用前者更新后者。这种操作也被叫做「松弛」。

这里暗含的信息是:每次选择「未确定节点」时,起点到它的最短路径的长度可以被确定。

可以这样理解,因为我们已经用了每一个「已确定节点」更新过了当前节点,无需再次更新(因为一个点不能多次到达)。而当前节点已经是所有「未确定节点」中与起点距离最短的点,不可能被其它「未确定节点」更新。所以当前节点可以被归类为「已确定节点」

/**
*根据题意,从节点 KK 发出的信号,到达节点 xx 的时间就是节点 KK 到节点 xx 的最短路的长度。
*因此我们需要求出节点 KK 到其余所有点的最短路,其中的最大值就是答案。
*若存在从 KK 出发无法到达的点,则返回 -1−1。

*下面的代码将节点编号减小了 11,从而使节点编号位于 [0,n-1][0,n−1] 范围。
**/
class Solution {
    public int networkDelayTime(int[][] times, int n, int k) {
        final int INF = Integer.MAX_VALUE / 2;
        int[][] g = new int[n][n];
        for (int i = 0; i < n; ++i) {
            Arrays.fill(g[i], INF);
        }
        for (int[] t : times) {
            int x = t[0] - 1, y = t[1] - 1;
            g[x][y] = t[2];
        }

        int[] dist = new int[n];
        Arrays.fill(dist, INF);
        dist[k - 1] = 0;
        boolean[] used = new boolean[n];
        for (int i = 0; i < n; ++i) {
            int x = -1;
            for (int y = 0; y < n; ++y) {
                if (!used[y] && (x == -1 || dist[y] < dist[x])) {
                    x = y;
                }
            }
            used[x] = true;
            for (int y = 0; y < n; ++y) {
                dist[y] = Math.min(dist[y], dist[x] + g[x][y]);
            }
        }

        int ans = Arrays.stream(dist).max().getAsInt();
        return ans == INF ? -1 : ans;
    }
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务