Dijkstra求最短路
作者:互联网
一、问题解析
原题链接:https://www.acwing.com/problem/content/851/
最短路问题是图论中的一个基本问题——给定一张有权图,如何求某两点之间的最短路径?
Dijkstra算法:
Dijkstra算法通常是求解单源最短路中最快的算法,但它无法处理存在负权边(权重为负数)的情况。Dijkstra本质上是一种贪心算法,通过不断调整每个点的“当前距离”最终得到最优结果,采用步步逼近的手段。
Dijkstra 算法是一种类似于贪心的算法,步骤如下:
1、当到一个时间点时,图上部分的点的最短距离已确定,部分点的最短距离未确定。
2、选一个所有未确定点中离源点最近的点,把他认为成最短距离。
3、再把这个点所有出边遍历一边,更新所有的点。
算法流程:
假设现在要求出某一点s到其他所有点的最短距离,对于每一个点v维护一个“当前距离” dist[v]
和 是否已确定最短距离 st[v]
。
-
初始化距离:首先将 dist[1] 初始化为0,将其他点的距离初始化为正无穷(可以是一个足够大的数)
-
迭代计算最短路,迭代
n
次。(有多少个点就循环多少次)-
从所有未确定最短距离的点中,找出当前距离最短的点
t
。(遍历dist[],找到未确定最短距离的点中最小的) -
将
t
标记为已确定最短距离的点。(st[t] = true;) -
用
t
来更新其它节点到1号点的距离。// 更新其它节点到1号点的距离 for (int j = 1; j <= n; j++) { // 因为当作无向图做,所以不用管,直接判断。没有路的话,g[t][j] = MAX,绝不可能 小于 dist[j]。 // g 存放每个点之间的距离,g[x][y]表示x->y的距离 if (dist[t] + g[t][j] < dist[j]) { dist[j] = dist[t] + g[t][j]; } }
-
直到所有的点都已经确定最短距离。这时
dist[]
中存的是1号点到各个点的最短距离。
-
二、代码实现
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
// 有向图是特殊的无向图
public class M {
static int N = 510;
static int MAX = 5000000;
static int n;
static int m;
// 存每个点之间的距离,g[x][y]表示x->y的距离
static int[][] g = new int[N][N];
// 存起点到每个点的距离
static int[] dist = new int[N];
// 存已经确定了最短路的点
static boolean[] st = new boolean[N];
static void dijkstra() {
// 初始化
Arrays.fill(dist, MAX);
dist[1] = 0;
// 循环n次,每次可以确定一个最小值
for (int i = 0; i < n; i++) {
// 存 离1号点最近的点
int t = -1;
// 找到当前距离1号点最近的点
for (int j = 1; j <= n; j++) {
/*
* 如果该点的最短距离未确定
* t = -1 表示刚开始 或者 后面的点比当前的点离1号点更近
* 这里不考虑有向图的指向性,当作无向图来判断就行(因为g中没有指向性的两个点之间的长度为正无穷,相当于没路)
*/
if (!st[j] && ( t== -1 || dist[j] < dist[t])) {
// 离1号点最近的点变为j点
t = j;
}
}
// 表示已经找到了确定了最短距离的点t
st[t] = true;
// 更新其它节点到1号点的距离
for (int j = 1; j <= n; j++) {
// 因为当作无向图做,所以不用管,直接判断。没有路的话,g[t][j] = MAX,绝不可能 小于 dist[j]。
if (dist[t] + g[t][j] < dist[j]) {
dist[j] = dist[t] + g[t][j];
}
}
}
// 如果等于MAX的话,那就说明没有路。输出 -1。
if (dist[n] == MAX) {
System.out.println(-1);
}else {
System.out.println(dist[n]);
}
}
public static void main(String[] args) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] splits = reader.readLine().split(" ");
n = Integer.parseInt(splits[0]);
m = Integer.parseInt(splits[1]);
// 先设定每个点之间的距离都为正无穷
for (int i = 0; i < g.length; i++) {
Arrays.fill(g[i], MAX);
}
// 将已有的距离信息填入 g
for (int i = 1; i <= m; i++) {
String[] arr = reader.readLine().split(" ");
int x = Integer.parseInt(arr[0]);
int y = Integer.parseInt(arr[1]);
int z = Integer.parseInt(arr[2]);
// 解决重边问题(一个点有两条边指向另一个点,只取最短的一条)
g[x][y] = Math.min(g[x][y], z);
}
dijkstra();
}
}
标签:dist,int,短路,算法,距离,Dijkstra,static,短距离 来源: https://www.cnblogs.com/Kled/p/16094951.html