1. 程式人生 > >多源最短路徑Floyd、Floyd求最小環【模板】

多源最短路徑Floyd、Floyd求最小環【模板】

Floyd演算法:用來找出每對點之間的最短距離。圖可以是無向圖,也可以是有向圖,邊權可為正,也可以為負,唯一要求是不能有負環。
1.初始化:將Map[][]中的資料複製到Dist[][]中作為每對頂點之間的最短路徑的初值,Pre[i][j] = i 表示 i 到 j 路徑中 j 的前一節點。
2. k 從 1 到 N 迴圈 N 次,每次迴圈中,列舉圖中不同的兩點 i,j,如果Dist[i][j] > Dist[i][k] + Dist[k][j],則更新Dist[i][j] = Dist[i][k] + Dist[k][j],更新Pre[i][j] = Pre[k][j]。
只要圖中不存在負環就可以得出正確的答案,關於Floyd演算法對負環的判定,參考下邊Floyd求最小環。

const int MAXN = 110;
const int INF = 0xffffff0;

int Map[MAXN][MAXN], Dist[MAXN][MAXN],Pre[MAXN][MAXN];
//Pre[i][j] = i表示i到j路徑中j的前一節點
void Floyd(int N)
{   //初始化
    for(int i = 1; i <= N; ++i)
    {
        for(int j = 1; j <= N; ++j)
        {
            Dist[i][j] = Map[i][j];
            Pre[i][j] = i;
} } for(int k = 1; k <= N; ++k) { for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { //如果Dist[i][j] > Dist[i][k] + Dist[k][j],則更新 if(Dist[i][k] != INF && Dist[k][j] != INF && Dist[i][k] + Dist[k][j] < Dist[i][j])
{ Dist[i][j] = Dist[i][k] + Dist[k][j]; Pre[i][j] = Pre[k][j]; //更新Pre[i][j] } } } } }

如果求點u到點v能達到的最長邊儘可能短的路徑上最長邊為多少,將迴圈內部改為如下程式碼:

int tMax;   //這裡邊求的是能達到的路徑上最長邊最小為多少  
                if(Dist[i][k] > Dist[k][j])  
                    tMax = Dist[i][k];  
                else  
                    tMax = Dist[k][j];  
                if(Dist[i][j] > tMax)  
                    Dist[i][j] = tMax;  

Floyd求最小環
不能在Map[][]陣列上直接計算,因為判斷過程中用到了Map[][]原始值。

const int MAXN = 110;
const int INF = 0xffffff0;
int temp,Map[MAXN][MAXN],Dist[MAXN][MAXN],pre[MAXN][MAXN],ans[MAXN*3];

void Solve(int i,int j,int k)
{
    temp = 0;   //回溯,儲存最小環
    while(i != j)
    {
        ans[temp++] = j;
        j = pre[i][j];
    }
    ans[temp++] = i;
    ans[temp++] = k;
}
void Floyd(int N)
{
    for(int i = 1; i <= N; ++i)
        for(int j = 1; j <= N; ++j)
        {
            Dist[i][j] = Map[i][j];
            pre[i][j] = i;
        }
    int MinCircle = INF;    //最小環
    for(int k = 1; k <= N; ++k)
    {
        for(int i = 1; i <= N; ++i)
        {
            for(int j = 1; j <= N; ++j)
            {
                if(i != j && Dist[i][j] != INF && Map[i][k] != INF && Map[k][j] != INF
                   && Dist[i][j] + Map[i][k] + Map[k][j] < MinCircle)
                {
                    MinCircle = min(MinCircle, Dist[i][j] + Map[i][k] + Map[k][j]);
                    Solve(i,j,k);   //回溯儲存最小環
                }
            }
        }

        for(int i = 1; i <= N; ++i)
        {
            for(int j = 1; j <= N; ++j)
            {
                if(Dist[i][k] != INF && Dist[k][j] != INF &&
                   Dist[i][k] + Dist[k][j] < Dist[i][j])
                {
                    Dist[i][j] = Dist[i][k] + Dist[k][j];
                    pre[i][j] = pre[k][j];  //記錄點i到點j的路徑上,j前邊的點
                }
            }
        }
    }

    if(MinCircle == INF)    //不存在環
    {
        printf("No solution.\n");
        return;
    }
    //如果求出最小環為負的,原圖必定存在負環
    for(int i = 0;i < temp; ++i)    //輸出最小環
        if(i != temp-1)
            printf("%d ",ans[i]);
        else
            printf("%d\n",ans[i]);
}

相關推薦

路徑FloydFloyd模板

Floyd演算法:用來找出每對點之間的最短距離。圖可以是無向圖,也可以是有向圖,邊權可為正,也可以為負,唯一要求是不能有負環。 1.初始化:將Map[][]中的資料複製到Dist[][]中作為每對頂點

路徑演算法:Floyd演算法

## 前言 由於本人太菜,這裡不討論Floyd的正確性。 ## 簡介 多源最短路徑,解決的是求從圖中任意兩點之間的最短路徑的問題。 ## 分析 程式碼短小精悍,主要程式碼只有四行,直接放上: ```cpp for(int k=1;kj和i->j作比較嗎,如果i->a->b->j比i->k->j更短呢? 這時

小生成樹(prime演算法kruskal演算法) 和 路徑演算法(floyddijkstra)

簡介: 帶權圖分為有向和無向,無向圖的最短路徑又叫做最小生成樹,有prime演算法和kruskal演算法;有向圖的最短路徑演算法有dijkstra演算法和floyd演算法。   生成樹

hihocoder 1089 路徑·二:Floyd演算法

http://hihocoder.com/problemset/problem/1089 描述 萬聖節的中午,小Hi和小Ho在吃過中飯之後,來到了一個新的鬼屋! 鬼屋中一共有N個地點,分別編號為1..N,這N個地點之間互相有一些道路連通,兩個地點之間可能有多條道路連通,但是並不存在一

路徑角度證明floyd演算法正確性

       floyd最短路徑演算法是用於求圖中任意兩點之間最短路徑的經典演算法,但是關於其正確性的證明書上以及網上並沒有很好的解釋。一年前自己從最短路徑結果本身出發想出了證明辦法,但是一直沒有發表,今天和朋友又聊起了這個話題,就整理了思路,寫出來,與大家分享。    

資料結構之(圖路徑之)Floyd(弗洛伊德)演算法

1)弗洛伊德演算法是求圖最短路徑的另外一種演算法,其適用於求圖中任意兩節點之間最短路徑; 2)其基本思想也是動態規劃,時間複雜度是O(N^3),N代表節點個數; 3)動態規劃的實現步驟是:a)找出問題的最優子結構;b)根據最優子結構求出遞迴解;c)以自下而上的方式求出最優解

python解決路徑問題:Floyd-Warshall演算法

昨晚做的華為實習生筆試題第三題的解答就涉及到最短路徑問題,今天查閱資料l,重新做了一下。 主要思路: 1.根據天氣狀況更新路線圖hmap 2.根據最新的路線圖hmap,運用最短路徑演算法Floyd-Warshall演算法,求得任意兩城市之間最短路徑所必須經過的城市,放在pa

HDOJ3790 路徑問題 --- SPFA演算法關鍵字短路

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

C++ dijkstra 路徑演算法top排序DFSBFS 示例 C++11

好一段時間前寫的了。。。正好現在在複習資料結構,重構了一下程式碼 首先先是 圖、點Vertex和邊AdjACent的定義 class JpGraph { public: class Vertex; class

MIT演算法導論公開課之第18課 路徑演算法Bellman和差分約束系統

Bellman-Ford 演算法 圖G=(V,E),選取s∈V作為圖的原點,此演算法可計算最短路徑δ(s,v)(v∈V)或報告出圖中存在負權值的環路。 Exercise 在路徑中存在負權值的環路時,將δ(s,v)設定為-∞。 Bellman-F

HYSBZ - 4016 路徑樹問題 點分治 + 路徑字典序

題目傳送門 題解:首先對於給定的圖,需要找到那些從1好點出發然後到x號點的最短路, 如果有多條最短路就要找到字典序最小的路,這樣扣完這些邊之後就會有一棵樹。然後再就是很普通的點分治了。 對於扣邊這個問題, 我們先跑一遍最短路,這樣就可以得到1號點到其他的點的距離。 然後在跑一遍dfs, 我們在跑dfs找

路徑Floyd-Warshall Algorithm

min algo ron 介紹 表示 解決 路徑 計算 最短距離 介紹:   是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負權(但不可存在負權回路)的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。   Floyd-Warshall算法的時間復雜度是O(N3)

Floyd路徑

多源最短路徑 void floyd()  {     for(i = 0; i < n; i++)     {         for(j = 0; j < n; j++)         {             d[i][j] = g[i][j];   //

路徑--Floyd演算法

#include<iostream> #include<cstdio> using namespace std; const int INF = 0x3f3f3f3f; int main(void) { int e[10][10] = { 0 }, dis[10], boo

Floyd 演算法路徑

1 #include <bits/stdc++.h> 2 3 typedef long long LL; 4 const int MAXN = 100; 5 const int INF = 0x3f3f3f3f; 6 using namespace std; 7

路徑基本介紹(1)--Floyd演算法(路徑,五行程式碼)

       我們來想一想,根據我們以往的經驗,如果要讓任意兩點(例如從頂點a點到頂點b)之間的路程變短,只能引入第三個點(頂點k),並通過這個頂點k中轉即a->k->b,才可能縮短原來從頂點a點到頂點b的路程。那麼這個中轉的頂點k是1~n中的哪個點呢?甚至有時候不只通過一個點,而是經過兩個點或

資料結構與算法系列----路徑Floyd-Warshall演算法)

任意兩點最短路徑被稱為多源最短路徑,即給定任意兩個點,一個出發點,一個到達點,求這兩個點的之間的最短路徑,就是任意兩點最短路徑問題,多源最短路徑,而Floyd-Warshall演算法最簡單,只有5行程式碼,即可解決這個問題。 上圖中有4個城市8條公路,公路上的數字表示這條

路徑演算法---Floyd-Warshall

暑假,小哼準備去一些城市旅遊。有些城市之間有公路,有些城市之間則沒有,如下圖。為了節省經費以及方便計劃旅程,小哼希望在出發之前知道任意兩個城市之前的最短路程。 上圖中有4個城市8條公路,公路上的數字表示這條公路的長短。請注意這些公路是單向的。我們現在需要求任意兩

(路徑算法整理)dijkstrafloydbellman-fordspfa算法模板的整理與介紹

void empty borde fast 默認 grand else 理解 scan 這一篇博客以一些OJ上的題目為載體。整理一下最短路徑算法。會陸續的更新。。。 一、多源最短路算法——floyd算法 floyd算法主要用於求隨意兩點間的最短路徑。也成

第六章 路徑——有向圖(Floyd-WarshallDijkstraBellman-Ford)

數組 opened 表示 printf 開始 style logs include 五行 一、Floyd-Warshall——加入點(多源最短路徑,核心算法只有五行) 城市之間的最短路徑 輸入: 4 8 1 2 2 1 3 6 1 4 4 2 3 3 3 1 7 3 4