课程学习--算法总结 图论算法(第4期)--最短路径--迪杰斯特拉(Dijkstra)Java描述

一、 概述
单源最短路径算法,从指定出发点到其他各个顶点的最短路径。

二、 相关参数

  1. root 起始节点
  2. visited[] 一维数组 记录节点是否访问
  3. dist[] 一维数组 起点到各个节点的距离

三、 算法流程描述

  1. 存图
  2. 初始化参数
  3. 遍历n次
  4. 更新visited
  5. 更新dist

四、 主要算法

  1. 取小算法
  2. 选择排序
  3. 广度优先
  4. 贪心思想

五、模板

package cn.charliejohn.graph.mp;

import java.util.Arrays;

/**
 * Dijkstra 单元内最短路径
 * 从出发点到其他各个顶点的最短路径, bfs
 * <p>
 *
 * @v: 出发顶点
 * @vertex[]: 顶点集合(未访问 : 0 ; 已访问 : 1)
 * @preVertex[] 前驱节点集合(取小后, 更新)
 * @dis[] v->Vi的距离(取小)
 * <p>
 * 步骤:
 * 1. 选取顶点(起点, 没有访问过中dis最小的)
 * 2. 更新三个数组(计算起点到目标的路径, 最小的话更新数组)
 * <p>
 * 例题:
 * 有 n 个网络节点,标记为1到 n。
 * <p>
 * 给你一个列表times,表示信号经过 有向 边的传递时间。times[i] = (ui, vi, wi),
 * 其中ui是源节点,vi是目标节点, wi是一个信号从源节点传递到目标节点的时间。
 * <p>
 * 现在,从某个节点K发出一个信号。需要多久才能使所有节点都收到信号?
 * 如果不能使所有节点收到信号,返回-1 。
 * <p>
 * 输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
 * 输出:2
 * @author: Charlie
 * @create: 2022/6/22 17:43
 */
public class NetworkDelayTime743 {

    /**
     * 一个集合最小的上界
     */
    final int SUP = Integer.MAX_VALUE >> 1;

    /**
     * @param times 图的原始数据
     * @param n     节点数
     * @param k     起始节点
     * @return
     */
    public int networkDelayTime(int[][] times, int n, int k) {
        // 图的邻接矩阵
        int[][] g = new int[n][n];

        // 存图
        for (int i = 0; i < n; ++i) {
            Arrays.fill(g[i], SUP);
        }
        for (int[] t : times) {
            int x = t[0] - 1;
            int y = t[1] - 1;
            g[x][y] = t[2];
        }

        // 每个顶点的距离
        int[] dist = new int[n];
        Arrays.fill(dist, SUP);

        // 起始节点
        dist[k - 1] = 0;

        // 顶点集合(未访问 : 0 ; 已访问 : 1)
        boolean[] used = new boolean[n];

        // 遍历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[], 第一次是起点
            used[x] = true;

            // 更新dist[]
            for (int y = 0; y < n; ++y) {
                // 起点到各点的距离, 不可达到就是SUP, 可达就是各个最短路径的累加
                dist[y] = Math.min(dist[y], dist[x] + g[x][y]);
            }
        }

        int ans = Arrays.stream(dist).max().getAsInt();
        // 无法到达则返回 -1
        return ans == SUP ? -1 : ans;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

charliejohn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值