Floyed-Warshall【弗洛伊德算法】

首先介紹一下有關最短路徑的知識c++

從某頂點出發,沿圖的邊到達另外一頂點所通過的路徑中,各邊上權值之和最小的一條路徑叫作最短路徑。解決最短路的問題有如下算法,Dijkstra算法,Bellman-Ford算法,Floyed算法和SPFA算法等。算法

                                                                                         ——百度百科數組

通俗點來講就是在圖中的兩點之間的最短距離(只不過這裏規定了路徑而已)spa


 

那麼,咱們的問題來了code

什麼是圖? 

圖(Graph【這也是爲何oier們一般設g數組的緣由】)是表示物件與物件之間的關係的數學對象,是圖論的基本研究對象。對象

簡潔來講,就是一個神奇的表示關係的圖表(別告訴我大家不知道圖表是什麼blog

什麼是權值?

在數學領域,權值指加權平均數中的每一個數的頻數,也稱爲權數或權重。ci

也就是這條邊的價值【相似於長度】get

 


那麼這裏對於一些基本的概念性的知識應該是沒有什麼問題了數學

說實話這個算法是用來求多源最短路徑的算法。

                  ——gh

                    ——題記【並Orz一波】

這裏的算法原理能夠看作是一個相對來講和DP有些關係的DP

這個神奇的算法的複雜度井然是O(n3)【使人十分慌張

但這個算法也有其必定的優勢:


1.能夠計算圖中任意兩點間的最短路徑

2.適用於負邊權的狀況

…………【好處不少,咱們要有一雙善於發現好處的眼睛

 

核心代碼相似於這個

for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if((i!=j)&&(i!=k)&&(j!=k)&&(f[i][k]+f[k][j]<f[i][j]))//這裏是一步鬆弛操做,使得f[i][j]是最短的 { f[i][j]=f[i][k]+f[k][j]; } } } }

其實很好理解

這裏放一個最簡單的例題給你們刷一刷吧

【洛谷P1744 採購特價商品】

這裏很好理解

就直接放代碼了

#include<bits/stdc++.h>
using namespace std; int a[101][3]; double f[101][101]; int n,i,j,k,x,y,m,s,e; int main() { cin>>n; for(i=1;i<=n;i++) { cin>>a[i][1]>>a[i][2]; } cin>>m; memset(f,0x7f,sizeof(f));//將這個矩陣初始化一下 for(i=1;i<=m;i++) { cin>>x>>y; f[y][x]=f[x][y]=sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2));//這就是兩點間距離公式了【注意須要強制類型轉換】,由於是無向的,因此f[x][y]=f[y][x] } cin>>s>>e; for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if((i!=j)&&(i!=k)&&(j!=k)&&(f[i][k]+f[k][j]<f[i][j])) { f[i][j]=f[i][k]+f[k][j]; } } } } printf("%.2lf",f[s][e]); }
相關文章
相關標籤/搜索