60 BFS的應用 求最短路徑

2021-08-21 16:07:42 字數 1868 閱讀 8309

這幾篇將主要根據我們之前所學的圖的遍歷演算法來解決一些問題,下面我們來看這樣的乙個問題。

問題:求不帶權連通圖g中從頂點u到頂點v的一條最短路徑。(即求頂點u到頂點v之間邊數最少的頂點序列)。

圖1-求最短路徑

例如,對於這樣的乙個有向圖,我們要求頂點0到頂點7的最短路徑。對於求最短路徑,我們是選擇dfs還是bfs呢?這是乙個值得思考的問題。

首先來看dfs深度優先搜尋:

圖2-dfs深度優先搜尋

如果採用dfs深度優先搜尋的話,得到的路徑可能是0 - 1 - 3 - 6 - 7這樣的路徑,而根據之前我們學習dfs深度優先搜尋過程可知,簡單來說,dfs深度優先搜尋就是選擇乙個方向(頂點),然後依次訪問下去(訪問鄰接點),直到訪問到終點為止,在這個過程中dfs深度優先搜尋並不關心這是否是一條最短路徑,而從最終搜尋到的路徑來看,這顯然不是一條最短路徑。

我們再來看bfs廣度優先搜尋:

圖3-bfs廣度優先搜尋

從圖3來看,bfs廣度優先搜尋是對每一層的所有相鄰的頂點進行搜尋,直到找到終點為止。在這個搜尋過程中,廣度優先搜尋會對所有的鄰接點進行了訪問,因此當廣度優先搜尋完成後,我們就可以知道有這樣的一條最短路徑可以到達頂點v(即序列:0 - 2 - 5 - 7)。

1. 從頂點u出發一層一層地向外擴充套件

2. 利用佇列記錄訪問的順序

3. 當第一次找到頂點v時佇列中便包含了最短路徑,同時在搜尋過程中利用佇列儲存最短路徑(這是乙個普通佇列,而非之前所說的環形佇列)

4. 然後再利用佇列輸出最短路徑(逆路徑)

如果你還是有些疑惑的話(比如逆路徑),不要急,接下來我們還會繼續介紹。

最好是先把bfs演算法先熟悉一下,有助於理解這個求最短逆路徑演算法,求最短逆路徑演算法的實現:

//求最短逆路徑演算法

void shortpath(algraph *g,int u,int v)

printf("%2d\n",qu[i].data);

break;

}//訪問w的所有鄰接點(這一步操作非常重要,體現bfs廣度優先搜尋,相信大家對這一步操作已經不陌生了吧)

圖4-求最短路徑演算法的過程

還記得前面我們說過的逆路徑嗎?求最短逆路徑演算法過程如圖4所示,bfs廣度優先搜尋會將所有搜尋到的頂點進行入隊,每個頂點入隊時會記錄兩項資訊,其中data域記錄頂點的資訊,parent域記錄上乙個頂點的下標位置。比如對於頂點5來說,data會記錄頂點5的值,而parent域會記錄頂點5的上乙個頂點2的下標位置(下標為2)。這樣我們就可以通過這種方式輸出逆路徑了。

而求最短逆路徑演算法中的頂點w則會記錄每個出隊的頂點,所以當頂點w為頂點7時,此時頂點w和頂點v相等,則說明找到了最短逆路徑,所以會從頂點7開始輸出,並根據頂點7的parent域找到上乙個頂點,並輸出頂點5,以此類推,直到頂點的parent為-1,這說明逆路徑就輸出完畢了。

BFS求最短路

假設有乙個n行m列的迷宮,每個單位要麼是空地 用1表示 要麼是障礙物 用0表示 如和找到從起點到終點的最短路徑?利用bfs搜尋,逐步計算出每個節點到起點的最短距離,以及最短路徑每個節點的前乙個節點。最終將生成一顆以起點為根的bfs樹。此時bfs可以求出任意一點到起點的距離。poj3984 bfs求最...

BFS求最短路

假設有乙個n行m列的迷宮,每個單位格要麼是空地 用1來表示 要麼是障礙物 用0來表示 如何找到從起點到終點的最短路徑?分析 要找到終點到起點的最短路徑,可以使用二叉樹的bfs,因為二叉樹的bfs的訪問順序就是結點到根節點的距離,從小到大訪問的,因此可以從迷宮圖的起點開始進行bfs的寬度優先遍歷。遍歷...

最短路 求最長最短路,求最短路的路徑

hdu 1595 find the longest of the shortest include include include include include include include include include include include include include defi...