迪傑斯特拉算法求最短路徑(java)

迪傑斯特拉算法求最短路徑(java)

    設G=(V,E)是一帶權的有向圖,源點爲v0,則迪傑斯特拉算法用來求v0到其他頂點的最短路徑。迪傑斯特拉算法是按路徑長度遞增的次序產生最短路徑的算法
    以此圖爲例 求v0到v3最短路徑的過程
圖片1
    dist[3]保存v0到v3的距離,最開始是無限大,即dist[3]=INF,所以迪傑斯特拉算法先找到v2,即dist[2] = 10
圖片2
    然後從v2出發,因爲v2到v3距離爲50(小於INF),即dist[2]+cost[2][3] < dist[3],然後更新dist[3] = 60
圖片3
    v0到其他點也是以上步驟,通過與v0相鄰的點從而求出其他點的路徑。
    下面爲代碼
輸入
6 8
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 50
4 5 60
輸出
圖片
  n爲頂點個數,m爲可達路徑個數,二維數組cost是圖的鄰接矩陣表示。先把cost初始化爲最大值,然後把可達路徑依次填入當中。
  這裏稍微有點難理解的就是rear數組與q數組,其實稍微模擬一下步驟,就可以很容易理解。
  剛開始初始化的時候,以v2,v3爲例
  q[2][0] = 0q[2][1] = 2rear[2] = 2
  q[3][0] = 0q[3][1] = 3rear[3] = 2
  這就相當於剛開始v0到v2的路徑爲0->2,v0到v3的路徑爲0->3
  之後更新的時候,因爲v0到v3需要經過v2,所以
  q[3][0] = 0q[3][1] = 2q[3][2] = 3rear[3] = 3
  然後輸出路徑0->2->3

import java.util.Arrays;
import java.util.Scanner;

public class Dijkstra1 {
    public static void main(String args[]){
        Scanner scanner = new Scanner(System.in);
        int n =  scanner.nextInt();
        int m = scanner.nextInt();
        int[][] cost = new int[n][n];
        for(int i = 0; i<n; i++){
            Arrays.fill(cost[i], Integer.MAX_VALUE);
        }
        for(int i = 0; i<m; i++){
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            int p = scanner.nextInt();
            cost[x][y] = p;
        }
        dijkstral(cost, 0, n);
    }
    public static void dijkstral(int[][] cost, int v, int n){
        int[] dist = new int[n];  //保存v到其他點的最短距離
        int[] s = new int[n];  //保存已計算過的頂點
        int[] rear = new int[n];  //rear[i]保存v到頂點i的最短路徑頂點數
        int[][] q = new int[n][n];  //q[v][i]保存v到i的最短路徑

        //初始化s和rear
        for(int i = 1; i<n; i++){
            s[i] = 0;
            rear[i] = -1;
        }
        //初始化dist和q
        for(int i = 1; i<n; i++){
            dist[i] = cost[v][i];
            if(dist[i] < Integer.MAX_VALUE){
                q[i][++rear[i]] = v;
                q[i][++rear[i]] = i;
            }
        }
        s[v] = 1;
        int j, min, m;
        for(int i = 0; i<n-1; i++){
            min = Integer.MAX_VALUE;
            m = v;
            //尋找和v相鄰的最短距離的點
            for(j = 1; j<n; j++){
                if(dist[j] < min && s[j] == 0){
                    min = dist[j];
                    m = j;
                }
            }
            if(m != j){
                s[m] = 1;
                System.out.println(v + "到" + m + "的最短距離爲" + dist[m]);
                System.out.print("最短路徑爲: ");
                for(int k = 0; k<=rear[m]; k++){
                    if(k == rear[m]) {
                        System.out.print(q[m][k]);
                        break;
                    }
                    System.out.print(q[m][k] + "->");
                }
                System.out.println();
                //更新dist,就是上面所說的從v2出發
                for(int k = 1; k<n; k++){
                    if(dist[k] > (cost[m][k] + dist[m]) && s[k] == 0 && cost[m][k] != Integer.MAX_VALUE){
                        dist[k] = cost[m][k] + dist[m];
                        for(int k1 = 0; k1<=rear[m]; k1++){  //更新路徑
                            q[k][k1] = q[m][k1];
                        }
                        rear[k] = rear[m];
                        q[k][++rear[k]] = k;
                    }
                }
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章