Loading

【题解】CF1408H Rainbow Triples

一道值得深入思考的题。

第一眼带给人的感受就是这题大概是个网络流题,并且是模拟网络流。那么肯定是先建网络流模型。不过如果直接考虑三元组匹配的话不太好做。

接下来就是本题的关键点:观察到答案上界为 \(\lfloor\frac{cnt_0}{2}\rfloor\),考虑找到第 \(\lfloor\frac{cnt_0}{2}\rfloor\)\(0\) 所在的位置 \(L\),将序列分成 \([1,L]\)\([L+1,n]\) 两部分。这样的话,就只需要考虑一边匹配两个,在另外一边匹配一个 \(0\) 的情况了(注意到如果一组匹配三个元素都属于某一边,一定能够调整使得其满足上述情况)。

这样做有什么好处呢?我们可以不用管另外一边的那个 \(0\) 了:只需要找到匹配的二元组,接下来分配 \(0\) 就很好计算了。那么此时问题从三元组匹配变成了二元组匹配,简单了许多。

接着考虑网络流建模,对于每一个权值从 \(S\) 连边。因为对于左边部分的话,权值的位置越靠右匹配选项越多,只需要保留最右边的,右边部分同理,那么每个权值只需要对左右部分最多两个位置连边。接着就是 \(0\) 位置向 \(T\) 连边,权值位置去匹配 \(0\) 位置可以在位置之间连边权为 \(\infty\) 的边解决。

最后的图是形如这样的:

此时考虑最小割,如果不去割一个权值,那么就需要保证该权值不与 \(T\) 联通,会割掉一段左边部分前缀的边和右边部分后缀的边。那么考虑枚举割掉左边部分哪个前缀的边,用线段树维护割掉右边某个前缀的边的答案即可。

代码:Submission #131033316 - Codeforces

posted @ 2021-10-07 13:57  Qiuly  阅读(68)  评论(0编辑  收藏  举报