看完题目,我很熟练的建立了一个这样的毒瘤图
于是我快乐的 AC
了它。
int main() {
scanf("%d%d", &m, &n);
memset(head, -1, sizeof head);
rep(i, 1, m) { scanf("%d", &s); addEdge(0, i, s); }
s = 0, t = n * (m + 1) + 1;
rep(i, 1, n) {
int a, x;
scanf("%d", &a);
int base = (m + 1) * (i - 1);
int r = (m + 1) * i;
rep(j, 1, a) {
scanf("%d", &x);
addEdge(base + x, r, inf);
addEdge(r, base + x, inf);
}
scanf("%d", &x); addEdge(r, t, x);
if (i < n) {
rep(j, 1, m)addEdge(base + j, base + j + m + 1, inf);
}
}
printf("%d\n", Dinic());
}
但是,我眉头一皱,发现事情并不简单
\(5700ms\) ...
算了一下,大概有 \(n*(m+1)+1\) 这么多个点, \(1e5\) ... 边开了 \(1e6\) 才过
虽然说复杂度很宽松 , \(O(n^2m)\) ..
于是我看了一眼题解, 只有 \(n\) 个点
“在面对网络流问题时,如果一时想不出很好的构图方法,不如先构造一个最直观,或者说最“硬来”的模型,然后再用合并节点和边的方法来简直化这个模型。经过简化以后,好的构图思路自然就会涌现出来了。这是解决网络流问题的一个好方法。”
很显然我这个就是最原始的。
实际上这个图是可以合并的
可以把每一层的 $m + 1 $ 个点进行合并成一个点,记录下每个