CF1383F Special Edges
原题:给定一个 \(n\) 个点, \(m\) 条边的有向图 \(G\) ,每条边有一个容量;其中有 \(k\) 条边容量未定。
\(q\) 组询问,每次给出那 \(k\) 条边的容量。求 \(1 \to n\) 的最大流。
边的容量不会超过 \(25\) 。时限 \(5s\) 。
首先,最大流等于最小割;
注意到 $ k\le 10$ , 那么,对于每次询问可以 \(2^{k}\) 大力枚举那 \(k\) 条边的割或不割。
如果我们能预处理出不考虑那 \(k\) 条边的边权时那 \(2^k\) 种状态所对应的最小割的话,就可以在预处理的基础上加上当前状态割掉的边的边权和来计算当前状态的最小割了。
这样就能做到 \(O(2^k)\) 单次回答。
那么考虑预处理。首先考虑怎么表示一条边不割:
将其对应边权改为所有询问中这条边边权的最大值,或者直接改成 \(25\) 。
这样,如果在预处理时仍然选择割掉这条边,在询问时这条边也一定会割掉;那么,枚举这条边状态为割时,答案一定比当前优秀。(当前这条边的贡献大于等于其真正的贡献)也就是说这个状态虽然不符合我们的定义,却不会影响答案。
否则,我们就表示了这条边不割。
表示一条边割就直接把它的边权标成 \(0\) 。这同时做到了强制割掉和不考虑边权。
考虑怎么求每种状态的最小割:最大力的做法就是对于每种状态跑一发最大流,复杂度……会直接暴毙;(你比较猛的话当我没说)
注意到如果以二进制表示每个状态,不割对应 \(1\) ,割对应 \(0\) ,那么每个状态对应一个值;
如果记录下每个状态跑完最大流后的残量网络的话,对于当前状态 \(\alpha\) ,我们就可以用 \(\alpha\) 去掉某一位上的 \(1\) 得到已经计算好的状态 \(\beta\), 在 \(\beta\) 的残量网络上加入去掉的 \(1\) 所对应的边作为 \(\alpha\) 的初始图,并以 \(\beta\) 的答案作为 \(\alpha\) 的初始答案。
然后在此基础上跑最大流。注意我们一次只会加入一条边权最多 \(25\) 的边,那么最多只会增广 \(25\) 次。此时比起每次尝试找出所有增广路的 \(\text{Dinic}\) ,每次只找一条增广路的 \(\text{FF}\) 反而显得更为优秀。
这道题中 \(\text{FF}\) 用 \(\text{bfs}\) 还是 \(\text{dfs}\) 是个好问题,详情参见这里 (这个贴还有令人心情愉快的功效)
状态值为 \(0\) 时可以一发 \(\text{Dinic}\) 求一下。
然后再稍微卡一下常就好了。