YBTOJ 二分图 & 网络流合集

收录 ybt 上亿些(怎么好像是全部)我永远也想不到的神仙二分图/网络流建模。

部分见这里

游戏

传送门

首先黑白染色将其变成二分图。

从特殊入手,先考虑完全匹配的情况,这时发现先手将棋子放在任意一个点,后手都可以将它移到完全匹配中当前点所对应的点上,最后先没有点可走的一定是先手,先手必败。

推广到一般情况,将二分图中的点分成删掉它后最大匹配数变/不变两类,容易发现一条边连接的两个点一定不同属于第二类。如果先手从第二类点开始,后手只能将棋子移到第一类点上,使自己变为特殊情况中的先手,后手必败。

然后就是快速求出所有第二类点的问题:先任意找一种最大匹配,不在当前最大匹配中的点一定是第二类点。从每个已经确定的第二类点 x x x 出发,找对面在最大匹配中的点 y y y,则最大匹配中 y y y 对应的点 z z z 也是第二类点,因为 ( y , z ) (y,z) (y,z) 一定可以被替换为 ( y , x ) (y,x) (y,x)

祭祀

传送门

Dilworth 定理:一个偏序集中的最长反链长度 = 最小不可重链覆盖。

推广到 DAG 上即为最长反链长度 = 最小可重链覆盖,于是类似 floyd 地求出传递闭包,就又转化为了最小不可重链覆盖。

没有二分图就创造二分图,把每个点拆成入点和出点,就变成了最大独立集问题,就可以求出最长反链长度 a n s ans ans

原题还要求一种构造方案和所有可能出现在最长反链上的点。先考虑第三问,每次强制一个点 x x x 选入反链,则和它有偏序关系的点都不能选入反链。若 x x x 在最长反链上,去掉这些点跑二分图得到的新最长反链长度就应该是 a n s − 1 ans-1 ans1;再考虑第二问,在求得的点集里每次令从前往后找到的第一个点在最长反链上,删除集合里跟它有偏序关系的点就好了。

消毒问题

传送门

不要成为黑白染色魔怔人啊()

考虑二维的情况,每次花费 1 1 1 的代价消除一整行或一整列一定最优,可以用最小点覆盖解决;三维的情况类似,每次消除一个横着或竖着的面一定最优,但我们不能三分图匹配,怎么转成二分图呢? n m k ≤ 5000 nmk\le 5000 nmk5000 可以得到 min ⁡ ( n , m , k ) ≤ 17 \min(n,m,k)\le 17 min(n,m,k)17,这个数据范围就支持状压枚举哪些横着的面被消除,剩下的面就变成二分图了,很巧妙。

炮塔攻击

传送门

横向和纵向的炮塔之间需要决策,就提示我们要把答案转成 t o t − tot- tot最小割。

t o t tot tot 的含义是什么?如果觉得是常见的敌人总数,那就废了。题中最好的结果是每个炮塔都能打到它能攻击到的值最大的点 m x mx mx,可以考虑令 t o t tot tot 为这些 m x mx mx 之和,发现 m x mx mx 之后的点一定不参与决策,而选择 m x mx mx 之前的点 v a l val val 的断边代价就是 m x − v a l mx-val mxval。又因为只有横向和竖向之间需要决策,容易想到拆点并在拆出的两个点之间连边 i n f inf inf 表示一定只能选一边。

那么具体的建图就是:

  • 对于一个横向炮塔 p p p,在拆出的横点上连接 ( s , p , i n f ) (s,p,inf) (s,p,inf),每次从当前点 u u u 向炮塔方向上的下一个点 v v v 连边,由于这条边割断表示选 u u u,所以连的就是 ( u , v , m x − v a l u ) (u,v,mx-val_u) (u,v,mxvalu)(令 v a l p = 0 val_p=0 valp=0 来表示不选);
  • 对于一个竖向炮塔 p p p,在拆出的竖点上连接 ( p , t , i n f ) (p,t,inf) (p,t,inf),每次同样从当前点 u u u 向炮塔方向上的下一个点 v v v 连边 ( v , u , m x − v a l u ) (v,u,mx-val_u) (v,u,mxvalu)

然后跑最小割就行了。

软件开发

传送门

为了避免变量重名以下每天毛巾需求数为 c i c_i ci,AB 方式处理所需时间分别为 t a , t b ta,tb ta,tb

首先显然是拆点,将一天拆成早上 i i i 和晚上 i + n i+n i+n,个人感觉难点是如何保证最小费用的方案对应的是最大流?首先连 ( s , i , c i , 0 ) (s,i,c_i,0) (s,i,ci,0) ( i + n , t , c i , 0 ) (i+n,t,c_i,0) (i+n,t,ci,0) 来限制流量;每天购买的毛巾可以直接给到晚上表示在这一天使用完,即连 ( s , i + n , i n f , f ) (s,i+n,inf,f) (s,i+n,inf,f);第 i i i 天用的毛巾用 A 方式处理后可以贡献给第 [ i + t a + 1 , n ] [i+ta+1,n] [i+ta+1,n] 天,显然不能全连上,但可以通过连接 ( i , i + n , i n f , 0 ) (i,i+n,inf,0) (i,i+n,inf,0) 表示每天可以把毛巾留给下一天,就只需要连 ( i , i + t a + 1 + n , i n f , f a ) (i,i+ta+1+n,inf,fa) (i,i+ta+1+n,inf,fa) 了,B 方式同理。

放置棋子

传送门

看完题解:卧槽。

首先显然要令点 i i i 表示第 i i i 行, i + n i+n i+n 表示第 i i i 列。容易想到枚举新放的总棋子个数,然后发现怎么也无法表示第 i i i 行和第 i i i 列数量相等的限制。

于是换一个东西枚举:枚举每行最多放置的棋子个数 l i m lim lim,即连接 ( s , i , l i m , 0 ) (s,i,lim,0) (s,i,lim,0) ( i + n , t , l i m , 0 ) (i+n,t,lim,0) (i+n,t,lim,0) 来限制流量,然后每一行向每一列连边,其中要区分必须放的边和可以放的边,就需要引入费用,如果跑最大费用最大流的话,那就设置必须边的费用大于可放边的费用。又因为要知道选了几条可放边,所以可以设必须边费用为 1 1 1,可放边费用为一个大于 n 2 n^2 n2 的值 q a q qaq qaq,选出的必须边数量即为 c o s t / l i m cost/lim cost/lim,可放边数量为 c o s t % l i m cost\% lim cost%lim

然后考虑第 i i i 行和第 i i i 列数量相等的限制,方法是连接 ( i , i + n , i n f , 0 ) (i,i+n,inf,0) (i,i+n,inf,0)。这是因为这样构建的图合法情况下最大流一定是 n × l i m n\times lim n×lim,因为想要最大费用,所以一定在所有必须边和可放边跑完之后才会跑 ( x , x + n ) (x,x+n) (x,x+n),这些流量 w w w 都是被剩下的。而 x x x 的流入流量和 x + n x+n x+n 的流出流量都是 l i m lim lim,被使用的流量都是 l i m − w lim-w limw,从而保证了相等。

数字配对

传送门

发现一个性质:设 c i c_i ci i i i 的质因数指数和,若 c x c_x cx c y c_y cy 奇偶性相同,则 ( x , y ) (x,y) (x,y) 一定不可以配对。那么久可以考虑二分图型的建模,即 c a i c_{a_i} cai 为奇数的和起点连边 ( s , i , b i ) (s,i,b_i) (s,i,bi),为偶数的和终点连边 ( i , t , b i ) (i,t,b_i) (i,t,bi),可以配对的 i i i j j j c a i c_{a_i} cai 为奇数)之间连边 ( i , j , i n f , c i × c j ) (i,j,inf,c_i\times c_j) (i,j,inf,ci×cj)

求的是费用非负的时候的最大流,可以二分流量,跑最大费用最大流即可。

线性代数

戳这里

终于完结了qwq

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值