最短路徑的求法可能都知道,弗洛伊德和迪克斯特拉。這兩種方法都是求一條最短路徑,如果你想求多條最短路徑那就只能選擇其他方法了。
網上已經有幾種演算法可以求多條最短路徑,最常見的就是刪邊法+迪克斯特拉。就是用狄克斯特拉求出一條最短路徑然後把最短路徑上的邊一條一條的刪除然後再求最短路徑。
這個方法比較容易想但是刪邊的時候比較麻煩。
那麼我們可不可以在floyd的方法上改進呢,我們想一想floyd的判斷方法是什麼if(a[i][j] > a[i][k]+a[k][j]) 我們就更換a[i][j],並且記錄路徑;
細心的人可能會發現我們既然可以用 > 篩選一條最短路徑那麼我們改變判斷條件 讓a[i][j] == a[i][k]+a[k][j]時我們儲存他們的路徑。當然這是可以的,但是現有的二維儲存路徑已經滿足不了了,必須改用三維我選用的是二維的vector(vectorpath).當大於時我們清除path當等於時我們增加path。**實現如下。
for (k =0 ; k< n; k++)
else if (a[i][j] == a[i][k] + a[k][j] && k!= i &&k !=j)
}
假如我們想知道有多少條最短路徑,我們先思考這個問題,高中時我們學過排列組合有三個地點 a b c, a到b有3條路徑, b到c有2條路徑。那麼a到c就有6條路徑,這個是簡單的排列組合問題。我們回到剛才的話題,i到j的路徑多少也等於i到k的路徑乘上k到j的路徑,如上面的f陣列。
當你想知道路過什麼點時你可以用書上的遞迴式來獲得當然你需要一點小的變動,如下
k = path[i][j].size();
if (k == 0)
for (m = 0;m < path[i][j].size(); m++)
到此分析結束,你再也不用為多條最短路徑煩惱了
#pragma once
#include #include using namespace std;
// floyd
class floyd : public cwnd
;
#include "stdafx.h"
#include "knowledge_graph.h"
#include "floyd.h"
#include #include using namespace std;
// floyd
implement_dynamic(floyd, cwnd)
floyd::floyd()
}} floyd::~floyd()
begin_message_map(floyd, cwnd)
end_message_map()
// floyd 訊息處理程式
void floyd::ppath(int i, int j)
for (m = 0;m < path[i][j].size(); m++)
} void floyd::floyd()
; for (i = 0; ia[i][k] + a[k][j])
else if (a[i][j] == a[i][k] + a[k][j] && k!= i &&k !=j)
}for (i = 0; i0)
}memset(b, 0, sizeof(b));}}
for (i = 0; i < n; i++)
{ofs<
工作後時間太忙了,只是利用部落格檢視資料,也沒關注過自己的部落格,看到這麼多朋友有需求,就貼出全部**吧,應該編譯不過,但是你們應該可以看懂啦。汲取了那麼多前輩的知識,也要學著付出啦
兩點間最短路徑及所有路徑
private setnodes private map links private mapweights nodes用於儲存所有節點,不重複 links為鄰接表 weights為邊上的權值。1 兩點間最短路徑 dijkstra演算法 實現 為 public path shortestpath in...
Dijstra求任意兩點間最短路徑並輸出
用迪傑斯特拉演算法求一點到其餘所有結點的最短路徑。先輸入乙個小於100的正整數n,然後輸入圖的鄰接矩陣 10000表示無窮大,即兩點之間沒有邊 最後輸入兩個0到n 1的整數表示兩個點。先用迪傑斯特拉演算法求給定的第乙個點到其餘所有結點的最短路徑。然後再輸出給定的兩個點之間的最短路徑 按順序輸出最短路...
Dijkstra演算法求兩點最短路徑
對於下圖使用dijkstra演算法求由頂點a到頂點h的最短路徑,按實驗報告模板編寫演算法。選取乙個起始點加入集合a,剩餘點加入集合b 計算集合b中的點到初始點的距離dis i 若不相鄰的距離無窮大,否則為權值 選取最小的dis i 計為dis x 並將點x加入集合a 更新和點x相鄰的點y的dis值 ...