题目大意
「WF 2012」Chips Challenge(UVA 1104)
给定一个 $n \times n$ 的棋盘,有些格子已经放上了黑色或白色的棋子。要求你在剩下的格子中摆放棋子,满足条件:
- 第 $i$ 行的黑子个数等于第 $i$ 列的黑子个数。
- 每行的黑子个数不大于总黑子个数的 $\frac{A}{B}$。
求最多再放多少黑子。
数据范围:$n \le 50$。
思路分析
枚举每行每列最多放 $k$ 枚黑子,这样第二个限制就变成了总黑子数量不能超过 $\frac{B \cdot k}{A}$。
考虑建图:
- $S$ 向 $R_i$ 连边,代价为 $0$,流量为这一行最多可能摆放的黑子数量。
- $C_i$ 向 $T$ 连边,代价为 $0$,流量为这一列最多可能摆放的黑子数量。
- $R_i$ 向 $C_i$ 连边,代价为 $0$,流量为 $k$。
- 如果 $(i, j)$ 可以不放零件,那么 $R_i$ 向 $C_j$ 连边,代价为 $1$,流量为 $1$。
图中流量的含义:先走第 $4$ 类边表示放置白子,之后如果有可行解,那么残量网络必定左右对称并且和 $S, T$ 相邻的边的的容量都不大于 $k$,这样就可以给剩下的格子全部放上黑子。
于是我们可以发现,如果网络满流,就形成了一个可行方案。而满流情况下最小的费用就是最少放置白子的数量。
时间复杂度 $O(n \times \text{MCMF}(n, n^2))$。
代码实现
1 |
|