关于模拟费用流的一些理解

bzoj4977 跳伞求生

这道题比较简单

直接考虑按子弹数从小到大排序,扫到敌人加进堆里

扫到一个队友就考虑是匹配一个敌人或者是替换掉以前一个队友

这里满足偏序关系并且敌人是不能反悔换掉原来选择的一个敌人的

所以正确性有保障

「ICPC World Finals 2018」征服世界

这道题的最小费用最大流建图还是比较好想

首先我们把每一个终点的权值设为-inf

这样就把最小费用最大流转成了最小费用流

就可以考虑模拟费用流了

这道题的军队移动你选择的配对的起止点都是可以反悔的

注意到两个点之间的距离是

(dis[x]+dis[y]-2*dis[lca(x,y)])

其中dis是根节点到该点的距离

那么我们考虑把dis作为一个点的权值然后枚举lca计算答案

假设在一个点的子树z内

选择了起点x点和终点y点配对

我们就在起点的堆里加入-dis[y]+dis[z]*2

在终点的堆里加入-dis[x]+dis[z]*2

这样就可以在祖先处反悔

每一个点枚举两个堆的堆顶判断是否反悔即可

利用可并堆实现

code

「NOI2019」序列

这个题比较神

最大费用最大流建图需要一些思考

A集合每个数拆一个点

B集合每个数拆一个点

再加X,Y两个点

S,T总流量为k

(S->A_i (1,a_i))

(A_i->B_i (1,0))

(B_i->T (1,B_i))

这里就表示选择相同下标的可以选择最多k个

(A_i->X (1,0))

(X->Y (k-l,0))

(Y->B_i (1,0))

这里就表示(A_i)(B_j)可以配对

但是最多配(k-l)

这里由于题解说的我们发现他不会反悔

只会更改A与B之间的匹配方案

也就是不会放弃选某个A或某个B

只会更改原来与某个B匹配的A去变成另一个A

那么我们就可以考虑每一次添加1流量计算答案

理性思考发现新增一个流只有五种情况

我们记自由匹配表示(A_i->B-j)这种情况

(S->A_i->B_i->T)

选择一组(A_i)(B_i)都没被选的配对,这时自由匹配数不变

(S->A_i->X->Y->B_j->T)

选择一个(A_i)(B_j)配对,这时自由匹配数+1

(S->A_i->B_i->Y->X->A_j->B_j->T)

选择一个原来(B_i)(A_j)都在匹配中的(A_i)(B_j)配对

此时我们调整一下

(A_i)换去和(A_j)

(B_i)换去和(B_j)

此时自由匹配数会-1

(S->A_i->B_i->Y->B_j)

(S->A_i->X->A_j->B_j)

这两个都是选一个另外一个已经在匹配中的去配对

调整一下使得自由匹配数不变

于是我们只需要维护5个堆

维护一下

(a_i+b_i,a_i,b_i)(两个都没被选)

(a_i,b_i)((b_i/a_i)被选)

每次取最大的增广就好了

code

「LibreOJ NOI Round #2」黄金矿工

扔树上搞

我的题解

原文地址:https://www.cnblogs.com/deaf/p/13258548.html