最短路演算法彙總

2021-06-22 23:28:40 字數 1674 閱讀 4462

1、dijkstra

dijkstra演算法的思想是一種貪心的思想,它求得是單源最短路的問題,設定乙個頂點的集合,初始集合是源點,然後從源點出發,找到最近的點把該點納入這個集合,然後再從這個集合出發,把離源點最近的點納入集合,直到把所有的點納入集合。最後的到的即是從源點出發到其它所有的點的最短距離。

舉個例子:

求1到8的最短距離。我們用乙個集合g來代表點集,初識g,然後d陣列代表其它點到1的距離,初始d[1]=0,d[>1]=inf表示還沒確定。

第一輪,把1加入g集合,g,更新與1相鄰的點。d[2]=2,d[4]=1,d[6]=3,其它還是inf

第二輪,選擇到源點最短距離的點,即4,把它併入g,更新

d[2]=min,d[2]=2;

d[6]=min,由於map[4][6]=inf,所以d[4]=3;

d[7]=min,d[7]=3;

第三輪,選擇到源點最近的點,即2點,然後如上更新。

最後:

g,圖中所選的路徑既是到所有點的最短路徑。

2、floyd

這個演算法複雜度o(n*n*n),所以對於點比較少的時候還行。它的思想是這樣的:對於a,b節點之間的路徑,而該路徑對於k節點無非就是經過與不經過的問題。所以我們定義dis[a,b]為a到b的最短距離,我們可以列舉所有的k節點,在經過或不經過的所有k點的之中比較,得出a到b之間的最短距離。若符合dis[a,b]>dis[a,k]+dis[k,b],那麼我們就更新

dis[a,b]=dis[a,k]+dis[k,b];

**大概如下:

for(int k=0;kmap[i][k]+map[k][j]||map[i][j]==inf)

}

這裡要注意了,k迴圈必須放在外面,因為如果放在最內的迴圈的話,每次更新的時候dis[i,j]就馬上確定下來了,這樣做法是錯誤的:

可以看下面乙個例子:

如果放在內迴圈,那麼更新得到的dis[a,b]將是9,但正確的是6。放在內迴圈的話還沒來得及更新dis[b,d]這兩點就把a,b確定下來了,得到的答案顯然是不對的。若放在外迴圈的話,每一輪更新都會用到前面求得的dis,這有動態規劃的思想,直到最後所求的就是所有點兩兩之間的距離都是最短的。

3、spfa

在求最短路時如果有負權的邊dijkstra等演算法沒有用武之地,而bellman-ford的複雜度有過高,而spfa可高效的解決問題。

spfa的基本是思想是:用乙個d陣列來維護其它點到源點的距離,用乙個佇列來儲存要優化的點,每次從佇列裡出乙個點,並更新其它與該點相連的點到源點的距離,更新的這些點如果在佇列中,則不管,如果不在佇列中,則將其加入到佇列裡面。這樣不斷入隊出隊,直到隊列為空,結果就出來了。這種方法稱為動態逼近法。這個演算法還可以判斷是否存在負環,當每個節點出隊的次數超過了n次,那麼存在負環。

**如下:

int spfa(int start)}}

return low[n];

}

最短路大彙總

鬆弛操作 當dis i dis j g j i 時 dis i dis j g j i dijkstra 單源最短路 o n 2 本質是貪心 不能處理負邊 分成兩個集合 用vis標記 乙個是已經找到最短路的乙個是沒有找到最短路的 從已經找到最短路裡的點出發,進行鬆弛操作 找到其中最小的加入最短路的集...

最短路徑演算法 最短路

在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input 輸入包括多組資料。每組資料第一行是兩個整數n m n 100,m 10000 n...

最短路演算法

常用的最短路演算法有三種 disjkstra,floyd,ballman floyd 一 disjkstra演算法 dijkstra演算法要求圖上的權非負數。同樣使用於無向圖 html view plain copy include stdio.h hdu 2544 define maxsum 0x...