前言:Rothen is the strongest man
优秀而快乐的E-K算法
时间复杂度:O(nm^2),一般跑不满,所以可以处理1e3 ~ 1e4的网络
基本流程:
1.找到一条还有剩余流量的路,找到一条弧使得它的容量与其当前流量的差最小 ,也就是剩余的流量最小的一条边,那么对于这条路,我们把所有路径上的弧都加上这个最小值,这是一定可行的!操作后,这条边的流量就为现在的流量+最小差 (另外注意,当此条路中弧的剩余流量减少时,一定要增加其反向图的流量,因为f(x,y)=-f(y,x))
2.重复以上步骤直到找不到增广路(我这步骤二要跟不要有什么区别??由此看出其实E-K算法就是愉快的暴力求解,快乐就完事了!!)
注意事项:
1.添加反向边
2.将反向边的剩余流量一开始设置成零
3.记得每次将原图中的流量减去的时候一定要增加反向边的剩余流量!
Code
EK算法运用:
1.二分图最大匹配
这道题目是一个经典建模,首先源点连接所有的一部图,汇点连接所有的二部图, 然后把每条边的容量设置成1(显然是正确的,因为每次匹配后那一条边肯定不能再次使用了嘛)然愉快跑一边EK就过了
噫!好!双倍经验
Code
最小费用最大流
这东西直接把EK算法的BFS换成SPFA就行了,
注意细节
1.我采用了一种奇怪的存边方式,就是把边按起点排序,然后同时要维护其反向边的序号,于是我就给每一条边一个num,num相同的就是互为反向边的边,然后用一个桶存一下,搞个nxt记录反向边的序号,就可以了
2.每次updata一定要注意反向边!!!
3.waste 必须要赋值为当前waste 的相反数!f(x,y)=-f(y,x)!
4.要记住存一下前驱边(便于updata)
5.SPFA的时候判断现在这条边的剩余流量是否为0