一、 概述
单源最短路径算法,从指定出发点到其他各个顶点的最短路径。
二、 相关参数
- root 起始节点
- visited[] 一维数组 记录节点是否访问
- dist[] 一维数组 起点到各个节点的距离
三、 算法流程描述
- 存图
- 初始化参数
- 遍历n次
- 更新visited
- 更新dist
四、 主要算法
- 取小算法
- 选择排序
- 广度优先
- 贪心思想
五、模板
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;
}
}