版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
最近在找工作,把自己当时参加比赛用的最短路径算法复习一下,简单实现一下
图如下:
输入和输出数据:
Input:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
Output:
0 1 8 4 13 17
代码:
package arithmetic;
import java.util.Scanner;
public class minPath1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while ( sc.hasNextInt() ) {
int n = sc.nextInt();//节点数
int m = sc.nextInt();//给的边的连接个数
int[][] e = new int[m + 1][m + 1];//e[i][j]表示i到j的距离
for (int i = 1; i <= n; i++) {//初始化e,i到i的距离初始化为0,否则初始化为最大
for (int j = 1; j <= n; j++) {
if (i == j) e[i][j] = 0;
else e[i][j] = Integer.MAX_VALUE;
}
}
for (int i = 1; i <= m; i++) {//读入数据,初始化距离
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
e[a][b] = c;
}
int[] dis = new int[n + 1];//表示所求节点到其他节点的距离
int[] book = new int[n + 1];//记录节点是不是已经被遍历过了
for (int i = 1; i <= n; i++) {
dis[i] = e[1][i];
}
book[1] = 1;
dijkstra(e, dis, book, n);
for (int i = 1; i <= n; i++) {
System.out.print(dis[i] + " ");
}
}
}
private static void dijkstra(int[][] e, int[] dis, int[] book ,int n) {
int min = Integer.MAX_VALUE;
int mark = -1;
for (int i = 0; i <= n - 1; i++) {//循环除了所求节点的其他所有节点
for (int j = 1; j <= n; j++) {//找到离i节点最近的节点,而且没有被标记过的节点
if (book[j] == 0 && dis[j] < min) {
min = dis[j];
mark = j;
}
}
book[mark] = 1;//将这个节点标记为1,表示已经遍历过了
for (int j = 1; j <=n; j++) {//进行松弛
min = Integer.MAX_VALUE;
/**
* 首先求出离源节点i最近的节点mark,上面已经找出来了,接着判断与mark相连接的节点j,
* 现在已知源节点i到j的距离dis[j],那么对dis[j]与dis[j]+e[mark][j]的值进行判断,
* 如果大于,那么证明存在s-u-v的距离小于s-v的距离,这样最短路径就可以更新出来了。
*/
if (e[mark][j] < min) {
if (dis[j] > dis[mark] + e[mark][j]) {
dis[j] = dis[mark] + e[mark][j];
}
}
}
}
}
}