對於無權的圖來說:
若從一頂點到另一頂點存在着一條路徑,則稱該路徑長度為該路徑上所經過的邊的數目,它等於該路徑上的頂點數減1。
由於從一頂點到另一頂點可能存在着多條路徑,每條路徑上所經過的邊數可能不同,即路徑長度不同,我們把路徑長度最短(即經過的邊數最少)的那條路徑叫做最短路徑,其路徑長度叫做最短路徑長度或最短距離。
對於帶權的圖來說:
考慮路徑上各邊上的權值,則通常把一條路徑上所經邊的權值之和定義為該路徑的路徑長度或稱帶權路徑長度。
從源點到終點可能不止一條路徑,把帶權路徑長度最短的那條路徑稱為最短路徑,其路徑長度(權值之和)稱為最短路徑長度或者最短距離。
Floyd算法
Floyd算法(Floyd-Warshall algorithm)又稱為弗洛伊德算法、插點法,是解決給定的加權圖中頂點間的最短路徑的一種算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。該算法名稱以創始人之一、1978年圖靈獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德命名。
適用范圍:無負權回路即可,邊權可正可負,運行一次算法即可求得任意兩點間最短路。
優缺點:
Floyd算法適用於APSP(AllPairsShortestPaths),是一種動態規划算法,稠密圖效果最佳,邊權可正可負。此算法簡單有效,由於三重循環結構緊湊,對於稠密圖,效率要高於執行|V|次Dijkstra算法。
優點:容易理解,可以算出任意兩個節點之間的最短距離,代碼編寫簡單
缺點:時間復雜度比較高,不適合計算大量數據。
時間復雜度:O(n^3);空間復雜度:O(n^2);
任意節點i到j的最短路徑兩種可能:
- 直接從i到j;
- 從i經過若干個節點k到j。
map(i,j)表示節點i到j最短路徑的距離,對於每一個節點k,檢查map(i,k)+map(k,j)小於map(i,j),如果成立,map(i,j) = map(i,k)+map(k,j);遍歷每個k,每次更新的是除第k行和第k列的數。
步驟:
第1步:初始化map矩陣。
矩陣中map[i][j]的距離為頂點i到頂點j的權值;
如果i和j不相鄰,則map[i][j]=∞。
如果i==j,則map[i][j]=0;
第2步:以頂點A(假設是第1個頂點)為中介點,若a[i][j] > a[i][1]+a[1][j],則設置a[i][j]=a[i][1]+a[1][j]。
無向圖構建最短路徑長度鄰接矩陣:
模板代碼:
有向圖構建最短路徑長度鄰接矩陣:
步驟:
核心代碼: