這是我參與8月更文挑戰的第13天,活動詳情查看:8月更文挑戰算法
最短路徑與最小生成樹不一樣,路徑上不必定包含n個頂點markdown
把圖中頂點集合分紅兩組:post
第一組爲已求出其最短路徑的頂點集合S 第二組爲還沒有肯定最短路徑的頂點集合Uspa
算法流程圖 C++代碼實現code
void ShortestPath_DIJ(AMGraph G, int v0){
// 用Dijkstra算法求有向網G的v0頂點到其他頂點的最短路徑
n = G.vexnum; // G 中頂點個數
for(v = 0; v < n; v++){
// n 個頂點依次初始化
S[v] = false; // S 初始爲空集
D[v] = G.arcs[v0][v]; // 將v0到各個終點的最短路徑長度初始化
if(D[v] < MaxInt) Path[v] = v0; // v0和v之間有弧,將v的前驅置爲v0
else Path[v] = -1; // 若是v0和v之間無弧,則將v的前驅置爲-1
}
S[v0] = true; // 將v0加入S
D[v0] = 0; // 源點到源點的距離爲0
/*―開始主循環,每次求得v0到某個頂點v的最短路徑,將v加到S集―*/
for(i = 1; i < n; i++){
// 對其他n-1個頂點,依次進行計算
min = MaxInt;
for(w = 0; w < n; w++)
if(!S[w] && (D[w] < min)){
v = w;
min = D[w]; // 選擇一條當前的最短路徑,終點爲v
}
S[v] = true; // 將v加入S
for(w = 0; w < n; w++) // 更新從v0出發到集合V−S上全部頂點的最短路徑長度
if(!S[w] && ((D[v] + G.arcs[v][w]) < D[w])){
D[w] = D[v] + G.arcs[v][w]; // 更新D[w]
Path[w] = v; // 更新w的前驅爲v
}
}
}
複製代碼
每一對頂點之間的最短路徑orm
方法一:每次以一個頂點爲源點,重複執行Dijkstra算法n次—— T(n)=O(n³) 方法二:弗洛伊德(Floyd)算法 算法思想:逐個頂點試探法圖片
typedef int Pathmatirx[MAXVEX][MAXVEX]
typedef int ShortPathTable[MAXVEX][MAXVEX]
/*- Floyd算法,求網圖G中各頂點v到其他頂點w最短路徑P[v][w]及帶權長度D[v][w] -*/
void ShrotestPath_Floyd(MGraph G, Pathmatirx* P, ShortPathTable* D){
int v, w, k;
for(v = 0; v < G.numVertexes; ++v){
// 初始化D與P
for(w = 0; w < G.numVertexes; ++w){
(*D)[v][w] = G.matirx[v][w]; // D[v][w]值即爲對應點間的權值
(*P)[v][w] = w; // 初始化P
}
}
for(k = 0; k < G.numVertexes; ++k)
for(v = 0; v < G.numVertexes; ++v)
for(w = 0; w < G.numVertexes; ++w)
if((*D)[v][w] > (*D)[v][k] + (*D)[k][w]){
// 若是通過下標爲k頂點路徑比原兩點間路徑更短
// 將當前兩點間權值設爲更小的一個
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k]; // 路徑設置爲通過下標爲k的頂點
}
}
複製代碼