1.什么是Dijkstra算法
Dijkstra算法,是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题(应用于无权图或所有边权相等的图时,等同于BFS)。其主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
2.算法思想
把顶点集合V分成两组:
(1)S:已求出的顶点的集合(初始时只含有源点V0)
(2)V-S=T:尚未确定的顶点集合
将T中顶点按递增的次序加入到S中,保证:
(1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度
(2)每个顶点对应一个距离值
S中顶点:从V0到此顶点的长度
T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度
依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和
3.算法步骤
G={V,E}
1. 初始时令 S={V0},T=V-S={其余顶点},T中顶点对应的距离值
若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值
若不存在<V0,Vi>,d(V0,Vi)为∞
2. 从T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中
3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值
重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止
4.实现代码
import java.util.Scanner;
public class Dijstra {
public static int Max = 100001;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入顶点数和边数:");
int vertex = input.nextInt(); //顶点数
int edge = input.nextInt();//边数
int[][] matrix = new int[vertex][vertex];
//初始化邻接矩阵
for (int i = 0; i < vertex; i++)
for (int j = 0; j < vertex; j++)
matrix[i][j] = Max;
System.out.println("请输入两个顶点号及他们之间的路径长度(结束时请输入0):");
for (int i = 0; i < edge; i++) {
int source = input.nextInt();
int target = input.nextInt();
int weight = input.nextInt();
matrix[source][target] = weight;
}
//单源最短路径,源点
int source = input.nextInt();
//调用dijstra算法计算最短路径
dijstra(matrix, source);
}
public static void dijstra(int[][] matrix, int source) {
int[] shortest = new int[matrix.length];//最短路径长度
int[] visited = new int[matrix.length];//判断该点的最短路径是否求出
String[] path = new String[matrix.length];//存储输出路径
//初始化输出路径
for (int i = 0; i < matrix.length; i++)
path[i] = new String(source + "->" + i);
//初始化源节点
shortest[source] = 0;
visited[source] = 1;
for (int i = 1; i < matrix.length; i++) {
int min = Integer.MAX_VALUE;
int index = -1;
for (int j = 0; j < matrix.length; j++) {
//判断加入新的节点后是否存在更短路径
if (visited[j] == 0 && matrix[source][j] < min) {
min = matrix[source][j];
index = j;
}
}
//更新最短路径,标记计算过的最短路径的节点
shortest[index] = min;
visited[index] = 1;
//更新从index跳到其它节点的较短路径
for (int m = 0; m < matrix.length; m++) {
if (visited[m] == 0 && matrix[source][index] + matrix[index][m] < matrix[source][m]) {
matrix[source][m] = matrix[source][index] + matrix[index][m];
path[m] = path[index] + "->" + m;
}
}
//打印最短路径
for (int n = 0; n < matrix.length; n++) {
if (n != source) {
if (shortest[n] == Max) {
System.out.println(source + "到" + n + "不可达");
} else {
System.out.println(source + "到" + n + "的最短路径是:" + path[n] + ",最短距离是:" + shortest[n]);
}
}
}
}
}
}
输入样例
7 10
0 1 6
1 2 5
0 3 2
3 1 7
3 4 5
1 2 5
1 5 3
4 5 5
5 4 2
4 6 1
0
输出样例
0到1的最短路径是:0->1,最短距离是:0
0到2的最短路径是:0->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:0
0到5的最短路径是:0->5,最短距离是:0
0到6的最短路径是:0->6,最短距离是:0
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:0
0到5的最短路径是:0->1->5,最短距离是:0
0到6的最短路径是:0->6,最短距离是:0
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:0
0到6的最短路径是:0->3->4->6,最短距离是:0
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:0
0到6的最短路径是:0->3->4->6,最短距离是:8
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:0
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:9
0到6的最短路径是:0->3->4->6,最短距离是:8
0到1的最短路径是:0->1,最短距离是:6
0到2的最短路径是:0->1->2,最短距离是:11
0到3的最短路径是:0->3,最短距离是:2
0到4的最短路径是:0->3->4,最短距离是:7
0到5的最短路径是:0->1->5,最短距离是:9
0到6的最短路径是:0->3->4->6,最短距离是:8