TC11054 - RabbitWorking 题解

先插一嘴,我模拟退火调参没调过去,但是 jgh 调过去了,这说明了什么(

考虑二分答案(想不到)。

对于答案 \(x\),chk 成功当且仅当存在非空集合 \(S\) 满足 \(\dfrac{\sum\limits_{i,j\in S,i<j}a_{i,j}}{|S|(200-|S|)}\geq x\),把讨厌的分母乘过去得到 \(\sum\limits_{i,j\in S,i<j}a_{i,j}-x|S|(200-|S|)\geq 0\)。我们考虑把 rabbit 看成点,把 \(a_{i,j}\) 看成边,那么这就与「点导出子图」很相似,即选了一些点就必须把它们之间的边给选上。

考虑把这个思路完善下去。\(-x|S|(200-|S|)\) 这东西怎么处理呢?拆开来得到 \(-200x|S|\)\(x|S|^2\)。前者直接在每个点上赋 \(-200x\) 即可。后者带个平方,那么边的数量是平方的,点是线性的。于是我们从中凑出与边的数量 \(\dfrac{|S|(|S|-1)}2\) 成正比的部分,得到 \(\dfrac{|S|(|S|-1)}2\cdot 2x+|S|x\),那么前面那部分给边,后面给点即可。

接下来就是要求这个图的边权、点权和最大的(非空)导出子图。这是个经典的玩意,我之前都不知道。事实上,它是可以转化成最大权闭合子图的。我们考虑将边看成点,将点连向边转化成的点表示点选了那么对应边必须选。但这样不符合导出子图,因为这样边一旦有一个点关联它就要选了,而导出子图要求两端都被选才要选。我们考虑个容斥,在点权上把周围一圈边给减到点权里。这样会发现最终边权选出来变成负的了,于是取个相反数即可。

总结起来,边权点权和最大的点导出子图转化为最大权闭合子图的方法是:令新图中的点权为旧图中的点权加上与之关联的边的边权,把旧图中的边在新图中用点表示出来,点权为原边权的相反数,关联它的两个点连向它。对应地,「边导出子图」问题是不可做的,因为你不知道在容斥的时候要减掉几份,而点导出子图中一条边只可能有恰好两个点关联它,情况可数。

那这题就直接做了,就看最大点导出子图的权值是否 \(>0\)(注意不能 \(\geq0\),因为要屏蔽空集)。这是个流量为实数的最大流,不过不慌,因为 Dinic 复杂度与流量无关。精度需要注意,这题精度要求很高,要把 eps 大胆设成 1e-9。

code

upd. 2021.2.5:发现边导出子图也是可做的,并且点 / 边导出子图转化成最大权闭合子图也是要有先决条件的,具体参见网络流刷题笔记 #72(虽然你看不到哈哈哈)

posted @ 2021-01-31 14:05  ycx060617  阅读(131)  评论(0编辑  收藏  举报