C 的最短路徑的弗洛伊德演算法案例講解

2022-09-29 21:54:30 字數 1895 閱讀 4409

現在我們有這麼一張圖:

我們要做的是求出從某一點到達任意一點的最短距離,我們先用鄰接矩陣來建圖,map[i][j]表示從i點到j點的距離,把自己到自己設為0,把自己到不了的邊初始化為無窮大,**為:

//初始化

for(int i=1; i<=n; i++)

for(int j=1; j<=n; j++)

if(i==j)

map[i][j]=0;

else

map[i][j]=inf;

//讀入邊

for(int i=1; i<=m; i++)

最後,建好的圖可以用**來表示:

現在,我們來思考,假設我們來找乙個中轉的點,看他們的路程會不會改變,我們先以1號頂點作為中轉點最為例子,製圖:

我們發現,圖有了變化,我們怎麼判斷以1號頂點作為中轉點圖的路程是不是更短呢,我們只需要判斷map[i][1]+map[1][j]的路程是不是比map[i][j]的路程更短,就可以判斷,

**為:

for(int i=1; i<=n; i++)

for(int j=1; j<=n; j++)

if(map[i][1]+map[1][j]

現在該怎麼辦呢,我們接著以2號頂點作為中轉點,很簡單**修改一句就就可以:

for(int i=1; i<=n; i++)

for(int j=1; j<=n; j++)

if(map[i][2]+map[2][j]www.cppcns.com map[i][j]=map[i][2]+map[2][j];

現在我們是不是發現了乙個規律,只要不斷的遍歷每乙個點,並且以每乙個點作為中轉點看看它的值會不會改變,就可以得到從乙個點到任意乙個點的最短路徑,也就是多源最短路,這就是弗洛伊德演算法,**為:

for(int k=1; k<=n; k++)

for(int i=1; i<=n; i++)

for(int j=1; j<=n; j++)

if(map[i][k]+map[k][j]encivkgjcaap[k][j];

這樣就可以遍歷每個頂點,找出所有的最短路,演算法的複雜度為o(n^3).

對於我一開始提出的問題,完整的**為:

#include

#include

#include

#include

#include

#include

#include

#include

#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

const int inf=1<<29;

int main()

//弗洛伊德(floyd)核心語句

for(int k=1; k<=n; k++)

for(int i=1; i<=n; i++)

for(int j=1; j<=n; j++)

if(map[i][k]+map[k][j] i=1; i<=n; i++)

return 0;

}給出樣例:

輸入:4 8

1 2 2

1 3 6

1 4 4

2 3 3

3 1 7

3 4 1

4 1 5

4 3 12

輸出:0 2 5 4

9 0 3 4

6 8 0 1

5 7 10 0

輸出的就是我建圖的時候用的**,可以表示任意一點到任意一點的最短距離。

如果有什麼不對的地方,歡迎指正~~

弗洛伊德演算法求最短路徑

include includeusing namespace std 鄰接矩陣的型別定義 define max 10000000 define max vertex num 20 typedef struct mgraph 構造有向網的鄰接矩陣 void createdn am mgraph g,i...

最短路徑 弗洛伊德 Floyd 演算法

弗洛伊德 floyd 演算法 是解決任意兩點間的最短路徑的一種演算法 floyd演算法是乙個經典的動態規劃演算法 用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做乙個詮釋 這個詮釋正是動態規劃最富創造力的精華所在 從任意節點i到任意...

最短路徑基礎演算法 弗洛伊德

問題 a 1171 基礎演算法 最短路徑問題 時間限制 1 sec 記憶體限制 64 mb 題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點間的直線距離。現在的任務是找...