简单学习了模拟费用流之后一直有点迷糊,后来在交流中似乎悟到了些什么。
能推出这道题挺开心的,而且对模拟费用流有了更进一步的理解。
首先这个题目很容易建出费用流的图。
考虑每次增广都会新增一对 \(a,b\),那么我们就需要起点向 \(\{a\}\) 连边,\(\{b\}\) 向终点连边,这样一条路径就一定会对应一对 \(a,b\)。
对于 \(K\) 个下标的限制,直接对起点拆点。
而对于至少的限制,我们把其转化成最多,即最多 \(K-L\) 对 \(c,d\) 不相同,这样也可以用一条流量为 \(K-L\) 的边表示。
而对于相同和不同的限制,如果相同那么显然可以直接流,即 \(a_i\) 向 \(b_i\) 连边。而如果不同,那么就需要通过上一行的边,所以建立两个辅助节点 \(L,R\),\(L\) 向 \(R\) 连 \(K-L\) 的边,然后 \(\{a\}\) 向 \(L\) 连边,\(R\) 向 \(\{b\}\) 连边。
因为我们在增广的同时要保证最大,所以在所有起点向 \(\{a\}\) 的边上和 \(\{b\}\) 向终点的边上加上他们的权值的费用,其它边的费用为 \(0\),这样就有了一个费用流的模型。
直接费用流肯定过不了,考虑模拟费用流。
我们可以发现一共有六种增广方式。 \[ \begin{aligned} &S \rightarrow A \rightarrow B \rightarrow T\\ &S \rightarrow A \rightarrow L \rightarrow R \rightarrow B \rightarrow T\\ &S \rightarrow A_1 \rightarrow L \rightarrow A_2 \rightarrow B_2 \rightarrow T\\ &S \rightarrow A_1 \rightarrow B_1 \rightarrow R \rightarrow B_2 \rightarrow T\\ &S \rightarrow A_1 \rightarrow L \rightarrow A_2 \rightarrow B_2 \rightarrow R \rightarrow B_3 \rightarrow T\\ &S \rightarrow A_1 \rightarrow B_1 \rightarrow R \rightarrow B_2 \rightarrow A_2 \rightarrow L \rightarrow A_3 \rightarrow B_3 \rightarrow T\\ \end{aligned} \] 在有下标的路径中,下标相同的点的位置相同。(如 \(A_1\) 和 \(B_1\) 的)
可以发现其中只有路径 \(2\) 会经过 \(L\rightarrow R\) 的边,所以我们可以先贪心把路径 \(2\) 走完,然后再增广 \(L\) 次。
考虑剩下的增广,设 \(P\) 为没选的点的集合,\(Q\) 为选了的点,且当前状态是用 \(L\rightarrow R\) 边形成的集合,\(O\) 为选了的点,且当前状态是用 \(A_i\rightarrow B_i\) 的边形成的集合。
那么对于剩下的五种路径,我们有以下限制: \[ \begin{aligned} A, B \in &P\\ \text{}\\ A_1, B_2 \in &P; &A_2 \in &Q\\ A_1, B_2 \in &P; &B_1 \in &Q\\ A_1, B_3 \in &P; &A_2, B_2 \in &Q\\ A_1, B_3 \in &P; &B_1, A_3 \in &Q; &A_2, B_2 \in O \end{aligned} \] 然后在增广完之后,上面的五条路径分别会出现这样的改变:
\(\text{insert } O\) | \(\text{delete } O\) | \(\text{insert } Q\) | \(\text{delete } Q\) | \(\text{insert }P\) | \(\text{delete }P\) | |
---|---|---|---|---|---|---|
\(\text{path 1}\) | \(A,B\) | \(A,B\) | ||||
\(\text{path 3}\) | \(A_2,B_2\) | \(A_1\) | \(A_2\) | \(A_1,B_2\) | ||
\(\text{path 4}\) | \(A_1,B_1\) | \(B_2\) | \(B_1\) | \(A_1,B_2\) | ||
\(\text{path 5}\) | \(A_2,B_2\) | \(A_2,B_2\) | \(A_1,B_3\) | \(A_1,B_3\) | ||
\(\text{path 6}\) | \(A_1,B_1,A_3,B_3\) | \(A_2,B_2\) | \(B_1,A_3\) | \(A_2,B_2\) | \(A_1,B_3\) |
可以发现改变量并不多。
那么我们用 \(5\) 个可删堆,分别维护:\(A,B\) 都在 \(P\) 的和的最大值,\(A\) 在 \(P\) 的最大值,\(B\) 在 \(P\) 的最大值,\(A\) 在 \(P\) 且 \(B\) 在 \(Q\) 的最大的 \(A\) 的权值,\(A\) 在 \(Q\) 且 \(B\) 在 \(P\) 的最大的 \(B\) 的权值。并同时维护 \(A,B\) 都在 \(Q\),\(A,B\) 都在 \(O\) 的对数,就可以通过这五个可删堆的拼凑,得到上述五条路径的最大值,修改的时候由于修改量很少,暴力更新可删堆即可。
总复杂度 \(O(\sum n\log \max\{n\})\)。
贴个代码
1 |
|
最后再来个总结:
模拟费用流究其根本是先建图,然后再分析图进行贪心模拟。