這個演算法。。
怎麼說........
學來也就是裝裝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...