[模板] 上下界网络流
上下界
上下界网络流指的是边的流量有上下界的一类网络流问题.
网络流
无源汇可行流
无源汇显然没有最大流:P
对于边 \((u, v, [l, r])\), 连边 \((u, v, r-l)\), 并且记录 \(v_u += l\), \(v_v -= l\).
然后, 建立超级源点\(ss\), \(tt\). 对于 \(v_p > 0\) 的点, 连边 \((p, tt, v_p)\); \(v_p < 0\) 的点, 连边 \((ss, p, -v_p)\).
然后跑 \((ss, tt)\) 的最大流, 当且仅当 \(ss\) 的所有出边都满流是有解, 且每条边 \(e\) 的真实流量为反向边的流量 \(+ l_e\).
事实上, 最终得到的可行流为原图中的若干个环 (复杂环).
有源汇可行流
注意到源点 \(s\) 和汇点 \(t\) 流量并不守恒.
因此, 连边 \((t, s, +\infty)\). 然后问题就变成无源汇的可行流了.
有源汇最大流
根据有源汇可行流的方式建图;
先跑 \((ss, tt)\) 的最大流, 然后再跑 \((s, t)\) (而不是 \((ss, tt)\)) 的最大流, 第二个流量即为答案.
有源汇最小流
根据有源汇可行流的方式建图;
先跑 \((ss, tt)\) 的最大流, 记 \((t,s)\) 的真实流量 (即为反向边流量) 为 \(f_0\);
然后删掉 \((t,s)\) 及其反向边 (否则 \(f_1\) 会变为 \(+\infty\)), 再跑 \((t, s)\) 的最大流, 记流量为 \(f_1\), 最小流即为 \(f_0 - f_1\).
费用流
最小费用可行流
先提一下这个...
利用spfa不断找最短路增广, 直到找到的最短路长度为正或找不到, 得到的即为最小费用可行流.
边的处理
对于边 \((u, v, [l, r], cost)\), 连边 \((u, v, r-l, cost)\), 并在答案中加上 \(l \cdot cost\); 记录 \(v_u += l\), \(v_v -= l\).
然后, 建立超级源点\(ss\), \(tt\). 对于 \(v_p > 0\) 的点, 连边 \((p, tt, v_p, 0)\); \(v_p < 0\) 的点, 连边 \((ss, p, -v_p, 0)\).
和无费用的流基本相同. 事实上, 最大流可以看做一个费用为0的最小费用最大流.
另一种建法: 对于边 \((u, v, [l, r], cost)\), 连边 \((u, v, r-l, cost)\), \((ss, v, l, cost)\), \((u, tt, l, 0)\).
无/有源汇的可行/最大/最小费用流
和不带费用的版本几乎完全相同, 把边的处理方法换成上面的即可.
负权边的处理
回忆我们是如何处理上下界的流量限制的:
- 假设这条边流量为流量下界;
- 发现这时一些点不满足流量平衡限制, 然后通过附加源点和流量的方式满足每个节点流量平衡.
假设边的流量范围为 \([l, r]\), 那么这时我们假设的流量为 \(l\). 事实上, 流量只要为 \([l, r]\) 内的任意实数, 都能得到正确的可行流. 当流量过大时, 由于反向边 (反悔边) 的存在, 可以把流量缩小到正确的答案.
现在考虑一条负权边 \((u, v, [0,f], -c)\), 其中 \(c > 0\).
我们直接将这条边的流量设为 \(f\), 也即建立 \((u, v, 0, -c)\), 和反悔边 \((v, u, f, c)\). 那么, 这条负权边就变成了反向的正权边.
更进一步的, 我们可以消去图中所有的负权边以及负环. 这可以保证SPFA一定能得到正确答案.