一、問題引入java
帶權有向圖中單源點的最短路徑問題能夠用地傑斯特拉算法求解,若是要求解圖中每一對頂點之間的最短路徑,相似能夠想到的方法爲:每次以一個頂點爲源點,重複執行地傑斯特拉算法算法n次,這樣,即可以求得每一對頂點之間的最短路徑,總的執行時間爲O(n3)。算法
這裏能夠採用另一種求解算法:Floyd算法。數組
二、Floyd的基本思想爲:spa
從鄰接矩陣a開始進行n次迭代,第一次迭代後a[i,j]的值是從vi到vj且中間不通過變化大於1的頂點的最短路徑長度;第k次迭代後a[i,j]的值是從vi到vj且中間不通過變化大於k的頂點的最短路徑長度 第n次迭代後a[i,j]的值就是從vi到vj的最短路徑長度。code
三、算法描述:orm
(1) 用數組d[i][j]來記錄i,j之間的最短距離。初始化d[i][j],若i=j則d[i][j]=0,
若i,j之間有邊鏈接則d[i][j]的值爲該邊的權值,不然d[i][j]的值爲max 。
(2) 對全部的k值從1到n,修正任意兩點之間的最短距離,計算d[i][k]+d[k][j]的值,
若小於d[i][j],則d[i][j]= d[i][k]+d[k][j],不然d[i][j]的值不變。it
四、具體實現:io
帶權有向圖以下:class
在b.txt文件中保存的帶權有向圖的數據爲:import
其中第一個數據4表述圖中有4個節點,其餘的四行四列數據表示各個節點之間的路徑長度,9999表示兩個節點之間不可達。
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Floyd { public static int N; public static int[][] f; public static int[][] path; public static void floyd(){ int i,j,k; i = j = k = 0; for(i = 0; i < N; ++i) for(j = 0; j < N; ++j) for(k = 0; k < N; ++k) if(f[i][j] > f[i][k] + f[k][j]){ f[i][j] = f[i][k] + f[k][j]; path[i][j] = k; } print(); } public static void print(){ for(int i = 0; i < N; ++i){ for(int j = 0; j < N; ++j){ printPath(i, j); System.out.print("="+f[i][j]+"\t"); } System.out.println(); } } public static void printPath(int i, int j){ if(i == j || path[i][j] == -1) System.out.print(i+"->"+j); else{ printPath(i,path[i][j]); System.out.print("->"+j); } } public static void main(String[] args) { String p = "d:/b.txt"; try { Scanner s = new Scanner(new File(p)); while(s.hasNext()){ N = s.nextInt(); f = new int[N][N]; path = new int[N][N]; for(int i = 0; i < N; ++i){ for(int j =0; j < N; ++j){ f[i][j] = s.nextInt(); path[i][j] = -1; } } floyd(); } } catch (FileNotFoundException e) { e.printStackTrace(); } } }