多源最短路徑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]);
}
相關推薦
多源最短路徑Floyd、Floyd求最小環【模板】
Floyd演算法:用來找出每對點之間的最短距離。圖可以是無向圖,也可以是有向圖,邊權可為正,也可以為負,唯一要求是不能有負環。 1.初始化:將Map[][]中的資料複製到Dist[][]中作為每對頂點
多源最短路徑演算法:Floyd演算法
## 前言 由於本人太菜,這裡不討論Floyd的正確性。 ## 簡介 多源最短路徑,解決的是求從圖中任意兩點之間的最短路徑的問題。 ## 分析 程式碼短小精悍,主要程式碼只有四行,直接放上: ```cpp for(int k=1;kj和i->j作比較嗎,如果i->a->b->j比i->k->j更短呢? 這時
最小生成樹(prime演算法、kruskal演算法) 和 最短路徑演算法(floyd、dijkstra)
簡介: 帶權圖分為有向和無向,無向圖的最短路徑又叫做最小生成樹,有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排序、DFS、BFS 示例 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條公路,公路上的數字表示這條公路的長短。請注意這些公路是單向的。我們現在需要求任意兩
(最短路徑算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理與介紹
void empty borde fast 默認 grand else 理解 scan 這一篇博客以一些OJ上的題目為載體。整理一下最短路徑算法。會陸續的更新。。。 一、多源最短路算法——floyd算法 floyd算法主要用於求隨意兩點間的最短路徑。也成
第六章 最短路徑——有向圖(Floyd-Warshall、Dijkstra、Bellman-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