最短路徑 單源最短路徑Dijkstra(迪傑斯特拉)演算法 Floyd(弗洛伊德)演算法
阿新 • • 發佈:2018-12-19
兩個演算法的主要思想都是鬆弛,就是兩點間的距離通過第三點來變短
比如 1->3=10 1->2=2 2->3=5 這樣你就可以通過2號點把1,3兩點的距離縮短為7
Dijkstra演算法被稱為單源最短路,意思就是隻能計算某個點到其他點的最短路,而Floyd演算法
可以計算各個點之間的最短路徑。
舉個例子:有1~6 6個點 Dijkstra只能計算1號(或者2、3....其中某一個)點到其他點的最短路徑
而Floyd演算法就可以直接把1->2 1->3 .......任意兩點之間的最短路都算出來
當然Floyd的時間複雜度是比Dijkstra高的。
首先來看Floyd演算法
for (k=1;k<=n;k++)
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (e[i][j]>e[i][k]+e[k][j])
e[i][j]=e[i][k]+e[k][j];
使用K點對i,j兩點進行縮短(鬆弛),當從 i 到 k 再從 k 到 j 的距離小於從 i 直接到 k 的距離是 i 到 j 的距離就被縮短。
最終的圖就是一個全部為最短路的圖
再看Dijkstra演算法
首先來解釋一下什麼叫源,源其實就是起點,你想從哪一個點開始走的點。
單源最短就是單單這個點和其他各點的最短路。
因為是單源的所以我們就不必要設定一個二維陣列,可以設定一個一位陣列dis[],dis[i]表示的就是
源點到 i 的最短路徑。
先上程式碼:
void dijkstra(){ bool book[maxn]; memset(book,0,sizeof(book)); int m; for(int i=1;i<T;i++){ int min=INF; for(int j=1;j<=T;j++){ if(!book[j] && dis[j]<min){ min=dis[j]; m=j; } } book[m]=true; for(int k=1;k<=T;k++){ if(dis[k]>dis[m]+e[m][k]) dis[k]=dis[m]+e[m][k]; } } }
主要思想就是:先找到一個和源點最近的點,這個點和源點之間肯定是最短路了(因為不可能通過第三個點進行鬆弛了(負權除外)),標記這個點已經找到它到源點最短路,然後通過這個點對其他各個點進行鬆弛。重複上述步驟,知道標記完所有的點。
完活!