秒懂Dijkstra算法

Dijkstra算法是解决图中路径问题的,但只能解决一个点到所有点的所有最短路径。

主要有几步:

  1. 首先有个dis最短路径的数组,这个数组的含义是,目标点到其他点的路径;
  2. 其次需要维护一个vis数组,看是否更新过这个点。
  3. 遍历所有点,然后找当前没有访问过点的最小值。
  4. 然后更新此点到其他点的距离。

看文字感觉有点复杂,举个栗子就清晰了。

假设默认找从0到其他点的最短路径,dis数组为0 -> i 的最短距离。如果dis[2]就是0到2的最短距离,如果dis[100]就是0到100的最短距离。

leetcode 743. 网络延迟时间

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

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

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

已知:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2

直接上代码吧,解释代码


public int networkDelayTime(int[][] times, int n, int k) {
        int[][] map = new int[n + 1][n + 1];
        for (int[] ints : map) {
            Arrays.fill(ints, 10000);
        }
        // 初始化建立图
        for (int i = 0; i < times.length; i++) {
            map[times[i][0]][times[i][1]] = times[i][2];
        }
        int[] dis = new int[n + 1]; // k到其他点的距离数组
        int[] vis = new int[n + 1]; // 是否访问过了
        Arrays.fill(dis, 10000);
        for (int i = 1; i <= n; i++) {
            dis[i] = map[k][i];
        }
        dis[k] = 0;
        vis[k] = 1;
        // 遍历所有点。
        for (int i = 0; i < n; i++) {
            int max = 10000;
            int ids = 0;
            // 这里是找到一个没有访问过,并且是最小的节点。
            for (int j = 1; j <= n; j++) {
                if (vis[j] == 0 && dis[j] < max) {
                    max = dis[j];
                    ids = j;
                }
            }
            vis[ids] = 1;
            if (dis[ids] == 10000) continue;
            // 这里是更新本节点到其他点的最短距离,dis[ids]是k到ids,
            // map[dis][j]是dis到j,是否小于现在dis数组中的k到j。如果小于则更新。
            for (int j = 1; j <= n; j++) {
                if (vis[j] == 0 && dis[ids] + map[ids][j] < dis[j]) {
                    dis[j] = dis[ids] + map[ids][j];
                }
            }
        }
        int max = 0;
        for (int i = 1; i <= n; i++) {
            max = Math.max(max, dis[i]);
        }
        return max == 10000 ? -1 : max;
    }

如果有疑问可以评论留言,我会及时回复的。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值