最近在找工作,把自己當時參加比賽用的最短路徑算法複習一下,簡單實現一下
圖如下:
輸入和輸出數據:
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];
}
}
}
}
}
}