網路最大流演算法 最高標號預流推進HLPP

2021-09-07 16:27:28 字數 2037 閱讀 9479

這個演算法。。

怎麼說........

學來也就是裝裝13吧。。。。

長得比ek醜

跑的比ek慢

寫著比ek難

大家先來猜一下這個演算法的思想吧:joy:

看看人家的名字——最高標號預留推進

多麼高階大氣上檔次2333333咳咳

從它的名字中我們可以看出,它的核心思想是—推進,而不是找增廣路

那麼它是怎麼實現推進的呢?

很簡單,我們從源點開始,不停的向其他的點加流量,對於每個點都如此操作。那麼推到最後,我們就可以得到到達匯點的最大流量

不過可能會出現一種情況,就是$a$送流量給$b$,$b$覺得不好意思不想要,於是又推給$a$,$a$非常熱情便又推給$b$……直到推到tle為止。。那怎麼解決這種情況呢?

我們對每個點,引入乙個高度$h$,並且規定,乙個點$u$可以向另乙個點$v$送流量,當且僅當$h[u]=h[s]+1$

這樣我們就可以保證不會有上面情況發生了

另外還有一種情況,就是這個點依然有流量,但是迫於高度的限制流不出去,那怎麼辦呢?

很簡單,我們增加這個點的高度,這樣這個點的流量就能流出去了。

預留推進也就是這些內容了

但是它的名字裡的最高標號是啥意思呢?

這個要感謝咱們的熟人tarjan,他和他的小夥伴發現,如果每次選的點是高度最高的點,時間複雜度會更優。

可以優化至$o(n^2\sqrt)$

另外還有乙個比較顯然的優化,如果乙個高度$i$是不存在的,即圖中沒有高度為$i$的點,那麼從比$i$高的點一定不會走到匯點$t$,因為根據我們的限制條件,必須要經過高度為$i$的點,於是這些點就沒有用了

題目在這兒

不是我說,這個演算法真的是死慢死慢的,,,,

每個節點的高度

int f[maxn];//

每個節點可以流出的流量

int gap[maxn];//

每個高度的數量

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)struct

comp

inline

bool

operator

< (const comp &a) const

};priority_queue

q;bool work(int u,int v,int

id)inline

inthlpp()

++gap[ ++h[p] ];//

高度+1

q.push( comp(p,h[p]) );}}

return

f[t];

}int

main()

printf("%d

", hlpp() );

return0;

}

最高標號預流推進演算法

from queue import queue from queue import priorityqueue class graph def init self,s,t,m 源,匯,頂點個數 self.edge self.s s 源 self.t t 匯 self.num m 頂點個數 self....

poj1459最高標號預流推進演算法解題報告

題目意思不再所說,前面已給過乙個ek演算法的解題報告,下面給出網路流中求最大流幾乎最快的演算法 最高標號預流推進演算法的源 include define max 65535 using namespace std int s,t,n,np,nc,m,level int h 103 e 103 d 1...

最大流問題預流推進演算法(最基本)

name 最大流問題預流推進演算法 author 巧若拙 date 14 06 17 09 26 description 最基本的預流推進演算法,沒有任何優化,每次遍歷所有的結點,找出活結點,尋找可行弧,並預流推進,若沒有可以push的頂點,執行relabel操作。include include u...