在乙個無權的圖中,若從乙個頂點到另乙個頂點存在著一條路徑,則稱該路徑長度為該路徑上所經過的邊的數目,它等於該路徑上的頂點數減1。由於從乙個頂點到另乙個頂點可能存在著多條路徑,每條路徑上所經過的邊數可能不同,即路徑長度不同,把路徑長度最短(即經過的邊數最少)的那條路徑叫作最短路徑或者最短距離。
對於帶權的圖,考慮路徑上各邊的權值,則通常把一條路徑上所經邊的權值之和定義為該路徑的路徑長度或帶權路徑長度。從源點到終點可能不止一條路徑,把帶權路徑長度最短的那條路徑稱為最短路徑,其路徑長度(權值之和)稱為最短路徑長度或最短距離。
全稱為floyd—warshall。演算法用於求所有點對的最短距離。其時間複雜度為o(n^3)
這是乙個dp的過程
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j])
即從頂點i到j且經過頂點k的最短路徑長度。
**實現:
void floyd()
簡單描述dijkstra演算法是有荷蘭計算機科學家edsger wybe dijkstra提出。該演算法常用於路由演算法或者作為其他圖演算法的乙個子模組。舉例來說,如果圖中的頂點表示城市,而邊上的權值表示城市間的距離,那麼該演算法可以用來計算;兩個城市之間的最短路徑。
dijkstra單源最短路演算法,即計算從起點出發到每個點的最短路。dijkstra常常作為其他演算法的預處理。
使用鄰接矩陣的時間複雜度為o(n^2)
dijkstra演算法的思想
每次選擇已經訪問過(標記為true)的最短邊的點,並用這個點進行更新,更新的內容為未訪問的點到源點的最短路徑。(更新的過程:當該點到源點的距離加上到未訪問的點的距離小於未訪問過點到源點的距離的時候,對未訪問過的點的距離進行更新)。
舉乙個例子來說明演算法的過程
定義源點為0,dis[i]
為源點0到頂點的最短路徑。
其過程描述如下:
**實現
#include
#include
using namespace std;
int matrix[100][100]; ///鄰接矩陣
bool visited[100]; ///標記陣列
int dist[100]; ///源點到頂點i的最短距離
int path[100]; ///記錄最短路的路徑
int source; ///源點
int vertex_num; ///頂點數
int arc_num; ///弧數
void dijkstra(int source)
int min_cost; ///權值最小
int min_cost_index; ///權值最小的下標
for (int i = 1; i < vertex_num; i++) ///找到源點到另外vertex_num-1個點的最短路徑
}visited[min_cost_index] = true; ///該點已找到,進行標記
for (int j = 0; j < vertex_num; j++) ///更新dist陣列}}
}int main()
cout << "請輸入源點(
<< vertex_num << "):";
cin >> source;
dijkstra(source);
for (int i = 0; i < vertex_num; i++)
cout << "--"
<< source << endl;}}
return
0;}
詳解迷宮最短路問題
給定乙個n m的二維整數陣列,用來表示乙個迷宮,陣列中只包含0或1,其中0表示可以走的路,1表示不可通過的牆壁。最初,有乙個人位於左上角 1,1 處,已知該人每次可以向上 下 左 右任意乙個方向移動乙個位置。請問,該人從左上角移動至右下角 n,m 處,至少需要移動多少次。資料保證 1,1 處和 n,...
SPFA單源最短路詳解
適用範圍 給定的圖存在負權邊,這時類似dijkstra等演算法便沒有了用武之地,而bellman ford演算法的複雜度又過高,spfa演算法便派上用場了。我們約定有向加權圖g不存在負權迴路,即最短路徑一定存在。當然,我們可以在執行該演算法前做一次拓撲排序,以判斷是否存在負權迴路,但這不是我們討論的...
最短路演算法 Floyd基礎詳解
經典的最短路演算法是dijkstra演算法,但是這個演算法有兩點缺陷。1.一次dijkstra只能求單源的最短路徑,如果想要求任意兩點的距離,就要每乙個節點都進行一次dijkstra,很麻煩。2.運用dijkstra演算法時,要求圖中不可以有負權的邊。2是為何呢?可以看下圖 利用dijkstra演算...