網路最大流演算法 EK演算法

2022-05-02 12:15:11 字數 1775 閱讀 7342

ek演算法是求網路最大流的最基礎的演算法,也是比較好理解的一種演算法,利用它可以解決絕大多數最大流問題。

但是受到時間複雜度的限制,這種演算法常常有tle的風險

還記得我們在介紹最大流的時候提到的求解思路麼?

對一張網路流圖,每次找出它的最小的殘量(能增廣的量),對其進行增廣。

沒錯,ek演算法就是利用這種思想來解決問題的

ek演算法在實現時,需要對整張圖遍歷一邊。

那我們如何進行遍歷呢?bfs還是dfs?

因為dfs的搜尋順序的原因,所以某些毒瘤出題人會構造資料卡你,具體怎麼卡應該比較簡單,不過為了防止大家成為這種人我就不說啦(#^.^#)

所以我們選用bfs

在對圖進行遍歷的時候,記錄下能進行增廣的最大值,同時記錄下這個最大值經過了哪些邊。

我們遍歷完之後對這條增廣路上的邊進行增廣就好啦

題目在這兒

#include#include

#include

#include

#include

using

namespace

std;

const

int maxn=2*1e6+10

;const

int inf=1e8+10

;inline

char

nc()

inline

intread()

while(c>='

0'&&c<='9')

return x*f;

}struct

node

edge[maxn];

inthead[maxn];

int num=0;//

注意這裡num必須從0開始

inline void add_edge(int x,int y,int

z)inline

void addedge(int x,int y,int

z)int

n,m,s,t;

int path[maxn];//

經過的路徑

int a[maxn];//

s到該節點的最小流量

inline int

ek()

}if(a[t]) break;//

乙個小優化

}

if(!a[t]) break;//

沒有可以增廣的路徑,直接退出

for(int i=t;i!=s;i=edge[path[i]].u)//

倒著回去增廣

通過上圖不難看出,這種演算法的效能還算是不錯,

不過你可以到這裡提交一下就知道這種演算法究竟有多快(man)了

可以證明,這種演算法的時間複雜度為$o(n*m^2)$

大體證一下:

我們最壞情況下每次只增廣一條邊,則需要增廣$m-1$次。

在bfs的時候,由於反向弧的存在,最壞情況為$n*m$

總的時間複雜度為$o(n*m^2)$

ek演算法到這裡就結束了。

不過loj那道題怎麼才能過掉呢?

這就要用到我們接下來要講的其他演算法

網路流最大流 EK演算法

網路流是模仿水流解決生活中類似問題的一種方法策略,來看這麼乙個問題,有乙個自來水廠s,它要向目標t提供水量,從s出發有不確定數量和方向的水管,它可能直接到達t或者經過更多的節點的中轉,目前確定的是每條水管中水流的流向是確定的 單向 且每個水管單位時間內都有屬於自己的水流量的上限 超過會爆水管 問題是...

最大流 EK演算法

ek演算法。特別暴力 時間複雜度o v e 2 所以競賽中我們一般用效率更高的dinic演算法 ek演算法核心就是殘量網路圖,殘量指的就是每條路上剩餘的流量。不難發現,只要能在殘量網路圖上找到一條從源點到匯點的路,就能在這一條路上加流量,所加的流量就是在這條路徑上每條邊殘量取個min,一點一點的加就...

最大流 EK演算法

ek演算法是求最大流的一種容易實現 易懂的演算法。ek演算法仍然是乙個基於增廣路的演算法,思路非常簡單。每次從s嘗試找到一條到達t的路徑,路徑上最小的殘留量大於0,那麼我們就可以把這條路上的最小殘留量減去,累加到ans裡。繼續bfs直到找不到位置,此時ans就是最大流。ek增廣路演算法的時間複雜度為...