ACM之路 5 最短路演算法 Dijkstra演算法

2021-09-24 15:00:22 字數 2688 閱讀 8268

簡介:

dijkstra演算法是一種單源路徑演算法。時間複雜度為:o(n^2).比floyd演算法(o(n^3)快很多。當然,dijkstra演算法可以用堆優化後,演算法複雜度成了(o(m+n)logn),複雜度更底了。本文只講解dijkstra的簡單演算法。

問題:給予n個城市和m條道路,求從城市1到城市n的最短距離。(可見poj2387,5個城市,5條道路)

思路:與floyd演算法點鬆弛不同,dijkstra演算法通過鬆弛邊的做法找到從某乙個點到其他各個點的最小值。

比如我們求從點1到其他點的最短路徑。則設立乙個dist陣列表示從1到其他點的距離為 0 20 ∞ ∞ ∞ 100.

則,我們在這裡面先找到最短的路徑。20,則20這個點必然是1號到2號的最短路徑,這個點的值確定了。接下來,我們在根據這個已經確定的點,算其他邊,點2的出邊有3,比較1到3的距離原來是∞,然後1-2-3的距離變成20+30 = 50 (這個值小於∞,故可以更新這個點。即(dist陣列值變為:0 20 50 ∞ ∞ 100,)即把所有可能的出邊通過20這個最小距離,進行鬆弛比較,判斷哪個離得更近,選哪個。但是還有乙個要注意的是,1號點和2號點已經確定了,所以我們鬆弛的時候就不用看著兩個點了。怎麼區分這個點是否確定了呢,我們可以用乙個陣列vis來表示,如果看過了就設為1,否則為0。直到所有的點都被確定了。那麼dist陣列也就確定了,即1號點到其他每個頂點的最短距離。

步驟:(以從點1到點n為例)

1.初始化,構造乙個二維陣列 map 訪問地圖路徑長度,vis陣列表示這個點是否訪問過,dist陣列表示從訪問的起點到其他每乙個點的距離。

2.接下來,輸入每條路徑的值,更新到map中。其次,dist陣列也會更新成map[ 1 ][  j  ]相應的內容,即1號頂點到其他頂點的初始距離。  

3.先找dist陣列中最小值的點,迴圈從1開始,但是這裡的0是沒有意義的。沒有起到鬆弛作用。標記vis[1] = 1。接下來找未訪問過的,且是dist中的最小值。找到了點2,路徑是20,則20是1到2的最短路徑,確定了。(因為沒有比從1到其他點,再到2更短的路徑了,前提是沒有負權值)。20確定後,vis[ 2 ]設為1,表示已經訪問過了。然後再對3,4,5這三個點進行比較,看從1到3近還是1->2,2->3近,由dist知,1->3為∞,1->2->3為50,故50《無窮大, 則更新dist,同樣對1->4,1->2->4 和 1->5 ,1->2->5進行比較,發現更大了,故dist不更新。第二輪更新完畢。(第一輪是從vis[1] = 1開始,沒有太大意義)。

同樣第三輪,在找到  沒有被訪問過的頂點且dist最小值  即50,則令vis[3] = 1,標記訪問過且判斷其他未訪問過的頂點,能否鬆弛。發現,1->4由無窮大更新到了1->3->4 dist更新為70。

後面同理。直到所有的頂點都訪問過,dist的最後的值即為1號定點到其他頂點的最小值。

更新結果如上圖所示。:

**詳解:

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

#define inf 1<<29

using namespace std;

int map[1010][1010];

int dist[1010]; //從1到各個點的距離

int vis[1010]; //vis標誌這個點有沒有被訪問過

void dijkstra(int n)

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

}vis[k] = 1; //標誌k被訪問

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

}}int main()

}mem(dist,0);

mem(vis,0);

//input

for(i=1;i<=t;i++)

}//dijkstra演算法

dijkstra(n);

//output

printf("%d\n",dist[n]);

}return 0;

}

poj2387 til the cows come home 注意的點:

1.這是無向圖,所以記得輸入地圖資訊,雙向填寫。

2.比原來更小的值才更新,防止重複路徑。

3.注意找dist中的最小值時必須要求①。該點沒有被訪問過,②。最小值。

4.本題略坑的一點是注意城市和路徑順序,wa了好幾次,終於找到出錯點了。

最短路總結1 最短路問題概述與樸素dijkstra

最短路系列鏈結 最短路總結1 最短路問題概述與樸素dijkstra 最短路總結2 堆優化dijkstra 最短路總結3 bellmanford 最短路總結4 spfa及應用 最短路總結5 floyd 1.最短路問題概述 若網路中的每條邊都有乙個數值 長度 成本 時間等 則找出兩節點 通常是源節點和阱...

優先佇列優化的Dijk單源最短路演算法

開始以為優先佇列優化的是最短路的時間複雜度,現在看來,更多的是優化空間複雜度 我們是先用那個把圖變成樹的資料結構來儲存圖中所有的邊 如果我們用鄰接表儲存邊的話,空間複雜度為n 2也就是說我們的陣列最大能開到5000 5000 現在我們儲存邊,那麼就可以在點較多而邊較少的情況下搞定了 下面附上注釋詳盡...

複習之路 最短路演算法Dijsktra

dijkstra spfa floyd dijkstra演算法是一種單源最短路演算法,適用於無負權的圖。其採用了bfs 貪心的方式來更新最短路。初始化dis 每乙個點 dis 起點 0。標記起點,加入集合s。其他點不標記,加入集合u。從集合u中選取與當前點a距離最近的點b。若起點到點a的距離 點a到...