首先可以参考kactl 和 chillee的实现,都实现的非常精巧
https://github.com/kth-competitive-programming/kactl/blob/master/content/graph/PushRelabel.h
https://gist.github.com/Chillee/ad2110fc17af453fb6fc3357a78cfd28
论文中实现建议
http://infolab.stanford.edu/pub/cstr/reports/cs/tr/94/1523/CS-TR-94-1523.pdf
首先预期的方法是压入与重标记法,push & relabel的顺序在这类方法中没有规定,都是可以得到正确结果的,细致的实现特定顺序的push & relabel可以优化复杂度到n^3 or n^2 * sqrt(m)
一般采用最高标号来push & relabel
实现中可以有4个优化
1 bucket代替优先队列,因为优先队列维护的是height,是整数并且值域不大,可以用数组节约进出队列的Log
2 gap优化 不赘述
3 类似当前弧优化,在discharge的时候找从之前没访问过的开始,这里还有个细节,论文是while(ex[u] > 0) xxx
可以一次for,类似循环遍历adj[u]来(可能)实现局部一致性
4 global rebabeling, relabel一定次数后,重做从终点的残留图bfs,优化height。优化后的highest>=之前的highest,整个while不用做额外的事情