1. 程式人生 > >floyd演算法(求任意兩點間的最短路徑)

floyd演算法(求任意兩點間的最短路徑)

floyd演算法用於求任意兩點間的最短路徑,時間複雜度為O(n^3)

通過多次呼叫 Digkstar 演算法同樣能解決這個問題,時間複雜度同樣為O(n^3),但floyd更簡潔,利於程式設計。

floyd演算法的思想: 

        floyd是用一個n*m的鄰接表map[ n ][ m ]來存圖,通過對map的處理使得矩陣map[ i ][ j ]存的是點i到點j的最短距離。這是演算法是通過考慮最佳子路徑來尋找最短路的。

        具體思想是:能否在點a,b之間加入一塊跳板(即加入另外的點)使得a到b的距離縮短,如果可以的話更新a到b的距離,直到所有的點對都更新完。

        實現:

               for(k = 0; k < n; k++)

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

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

               if(map[ i ][ k ] + map[ k ][ j ] < map[ i ][ j ]) 

               map[ i ][ j ] =  map[i][k] + map[ k ][ j ];

floyd可以通過記錄“跳板”來記錄路徑:

               用矩陣pre[ i ][ j ]來儲存走到j的前一個點,初始化的時候儲存的都是起點(即i)。

               實現:

                         while( map[ i ][ j ].pre!=i )
                         {
                              cout<<pre[ i ][ j ];
                              k = pre[ i ][ j ];
                         }

        用floyd求最短距離並輸出路徑的具體程式碼

#include <iostream>
using namespace std;

const int INF = 99999999;

int n,m;//n:頂點數,m:邊數

struct node
{
    int space;
    int pre;
}map[110][110];//建圖,map[i][j].space表示點i到點j的最短距離,map[i][j].pre表示點i到點j的"跳板"

void input()
{
    int i,j;
    for(i = 0; i < n; i++)
    for(j = 0; j < n; j++)
    {
        if(i==j) map[i][j].space = 0;
        else map[i][j].space = INF;
        map[i][j].pre = i;
    }//初始化
    int a,b,x;
    for(i = 0; i < m; i++)
    {
        cin>>a>>b>>x;
        map[a][b].space = x;
    }//存圖
}

void floyd()//floyd演算法
{
    int k,i,j;
    for(k = 0; k < n; k++)
    for(i = 0; i < n; i++)
    for(j = 0; j < n; j++)
    {
        if(map[i][k].space!=INF && map[k][j].space!=INF && map[i][k].space + map[k][j].space < map[i][j].space)
        {
            map[i][j].space = map[i][k].space + map[k][j].space;
            map[i][j].pre = k;
        }
    }
}

void output()
{
    int i,j;
    for(i = 0; i < n; i++)
    for(j = 0; j < n; j++)
    {
        cout<<i<<"~"<<j<<"的最短距離:"<<map[i][j].space<<endl;
        int k = j;
        cout<<"路徑:"<<i<<" ";
        while(map[i][k].pre!=i)
        {
            cout<<map[i][k].pre<<" ";
            k = map[i][k].pre;
        }
        cout<<j<<" \n";
    }
}

int main()
{
    while(1)
    {
        cin>>n>>m;
        if(n+m==0)break;
        input();
        floyd();
        output();
    }
    return 0;
}

相關推薦

Dijkstra [迪傑斯特拉]演算法思路(單點到其他每個點的各個路徑Floyd演算法任意兩點短距離

先給出一個無向圖 用Dijkstra演算法(迪傑斯特拉演算法)找出以A為起點的單源最短路徑步驟如下 應用Dijkstra演算法計算從源頂點1到其它頂點間最短路徑的過程列在下表中。 Dijkstra演算法的迭代過程: Floyd演算法思想: 1、從任意一條單邊路徑開

floyd演算法(任意兩點路徑)

floyd演算法用於求任意兩點間的最短路徑,時間複雜度為O(n^3)。 通過多次呼叫 Digkstar 演算法同樣能解決這個問題,時間複雜度同樣為O(n^3),但floyd更簡潔,利於程式設計。 fl

poj 1125 Floyd演算法任意兩點短路

剛開始的時候一直不明白插點的順序為什麼不會對最後的結果有影響----一直不懂這個演算法--- 今天看見他們都學會了-.-終於把我也帶會了-- 對於原理的理解我還是通過輸出每一步更新後的結果搞明白的 開始一直不懂的是: 對於A-D: 更新B時--AB+BD>A

Floyd-Warshall演算法任意兩點短路(圖論演算法)

演算法思路簡介 假設只使用頂點0~k和 i,j ,並且我們記頂點i到j的最短路徑長為dp[ k + 1 ][ i ][ j ],k = -1表示只使用i,j,所以dp[ 0 ][ i ][ j ] = cost[ i ][ j ]. 只使用0~k時,有經

短路】兩點路徑的改進的Dijkstra算法及其matlab實現

inf 效率 func 圖論 表示圖 function nes 航空航天 ogr 代碼來源:《圖論算法及其matlab實現》(北京航空航天出版社) P18 書中提出了基於經典Dijkstra算法改進的兩種算法。 其中算法Ⅱ的效率較高。 代碼如下: 1 functio

演算法---每對頂點路徑

3.2、額外空間儲存2*(n*n)def floyd_warshall(W): import copy #需要兩個n*n矩陣的額外儲存 D_in = copy.deepcopy(W) D_ret = copy.deepcopy(W) k = 0 while k

JS實現深度優先搜尋得到兩點路徑

深度優先搜尋 效果: 找出圖裡點到點最短路徑,並列印軌跡 圖片如下所示: 程式碼: const map = [ [0, 1, 1, 0, 1], [1, 0, 0, 1,

Python廣度優先搜尋得到兩點路徑

前言 之前一直寫不出來,這週週日花了一下午終於弄懂了= =|| , 順便放部落格裡,方便以後忘記了再看看 要實現的是輸入一張 圖,起點,終點,輸出起點和終點之間的最短路徑 廣度優先搜尋 適用範圍: 無權重的圖,與深度優先搜尋相比,深度優先搜尋法佔記

AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法任意兩點路徑)(Bellman-Ford算法判斷負圈)

self logs var inf sel main rain test rect 題目鏈接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest

Floyd-Warshall 所有結點對的路徑演算法

以下程式碼僅支援結點是順序的,比如輸入5個結點,結點的編號只能是1到5,輸入順序可以不一致。 動態規劃真的簡潔,三個 for 把這麼複雜的東西就整理好了。 遞推公式:**d[i][j] = min ( d[i][j] , d[i][k] + d[k][j] )

C++任意兩點的所有路徑

基於連通圖,鄰接矩陣實現的圖,非遞迴實現。 演算法思想: 設定兩個標誌位,①該頂點是否入棧,②與該頂點相鄰的頂點是否已經訪問。   A 將始點標誌位①置1,將其入棧   B 檢視棧頂節點V在圖中,有沒有可以到達、且沒有入棧、且沒有從這個節點V出發訪問過的節點   C 如果有

兩點之間路徑:弗洛伊德算法

int code 指定 matrix ++ 計算 之間 logs 執行函數 弗洛伊德算法是計算無向有權圖中兩點間最短路徑的算法,復雜度為O(n^3)。其思路是將兩點間距離分為過(指定的)第三點或是不過,然後取它們的最小值,如此循環就可以得到兩點之間真正的最小值。 void

floyd演算法多源有權路徑

需要兩個矩陣 D矩陣儲存距離,D[i][j] 儲存的就是 i 到 j 點的距離; Path矩陣儲存路徑; Floyd 演算法不能解決有負值圈的情況; void Floyd(Graph G,int D[][Maxnum],int Path[][Maxnum]) { int i, j, k

用棧 迷宮問題(路徑和全部路徑

這是資料結構的作業,便找書邊看網上,然後自己慢慢寫出來的,這裡面主要是回溯法。 因為課本上是打印出一條路徑,然後我在想怎樣能將所有的路徑都輸出來,方法:就是當求出一條路徑後,將出口點變成可以走的點(因為之前將其值變成了-1),並且將棧頂元素出棧,還需要得到現在棧頂元素的i,j

圖論經典演算法(通俗易懂):路徑小生成樹

一、最短路問題 求圖的最短路問題,幾乎是圖論的必學內容,而且在演算法分析與設計中也會涉及。很多書上內容, 實在沒法看,我們的圖論教材,更是編的非常糟糕,吐槽,為啥要用自己學校編的破教材,不過據說 下一屆終於要換書了。 言歸正傳,開始說明最短路問題。

有向圖路徑條數

(2)Dijkstra演算法 使用兩次Dij演算法,第一次計算最短路徑,第二次計算路徑條數。 int cost[MAX][MAX],dist[MAX],dist2[MAX],num[MAX][MAX]={{0,0}},ci[MAX]={0}; //dist2[]是在第二次寫dijikstra時,記錄最短路

演算法導論】單源路徑之Dijkstra演算法

        Dijkstra演算法解決了有向圖上帶正權值的單源最短路徑問題,其執行時間要比Bellman-Ford演算法低,但適用範圍比Bellman-Ford演算法窄。 迪傑斯特拉提出的按路徑長度遞增次序來產生源點到各頂點的最短路徑的演算法思想是:對有n個頂點的有向連

演算法導論之單源路徑

單源最短路徑,在現實中是很多應用的,是圖的經典應用,比如在地圖中找出兩個點之間的最短距離、最小運費等。單源最短路徑的問題:已知圖G=(V,E),找出給定源頂點s∈V到每個頂點v∈V的最短路徑。單源最短路徑衍生出的變體問題如下: 1)單終點最短路徑問題:找出從每個頂點v到指定

(dijkstra演算法+多權值)路徑問題

給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。 Input 輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且

圖的深度優先和廣度優先遍歷及兩點路徑實現

通用遍歷 參考:https://segmentfault.com/a/1190000002685939 遍歷 圖的遍歷,所謂遍歷,即是對結點的訪問。一個圖有那麼多個結點,如何遍歷這些結點,需要特定策略,一般有兩種訪問策略: 深度優先遍歷 廣度優先遍歷 深度優先 深度優先遍歷