一道网络流题目和其相关套路:ZR2627紫罗兰

http://zhengruioi.com/problem/2627

Trick1:二分套网络流

首先可以对原图建模

在这里插入图片描述中间拆点是为了两对棋子走到同一个格子上

然后我们发现每条边除了容量还有一个边权, 而我们的目标是求出每一个流量下的最小边权

对于网络流中出现边权最值问题,可以进行二分。二分过程时枚举最值,然后保留可行边,来跑网络流

Trick2:动态加边维护增广路

对于能够在网络流上通过上述二分的问题,都可以通过这种方法。

考虑网络流找的是什么?增广路!

动态加入每条边,每次加完跑一遍增广路即可

Trick3:基于增广路数量的bfs

回到原题,发现增广路数量最多为 n 2 n^2 n2,所以让它最多增广 n 2 n^2 n2

维护一个 v i s vis vis 数组,表示一个点在增广 i i i 次后是否能在残量网络上到达。加入一条边 u → v u\to v uv,如果 v i s u = 1 , v i s v = 0 vis_u=1,vis_v=0 visu=1,visv=0,那么就可以让 v i s v = 1 vis_v=1 visv=1,并按照此方法bfs出去。如果此时到达了汇点,说明当前残量网络出现了一条增广路。 此时直接从汇点EK即可。注意在EK中还要维护反悔边!这样才能保证正确性。

EK的过程:

void EK() {
	int x=T; 
	while(x!=S) {
		G[x][pre[x]]=1; G[pre[x]][x]=0; 
		x=pre[x];  
	}
}

因此要在bfs过程中维护一个 p r e pre pre

Trick4:bitset维护bfs过程

令每个点的出边集合为 G u G_u Gu,那么bfs中有用的点 v v vG[u]&(~vis),bitset维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值