生成二进制矩阵的算法

Algorithm to generate a binary matrix

给定两个输入数组 [R1, ..., Rn] 和 [C1, ..., Cn]。我们要创建一个二进制矩阵 A(大小为 nxn),使得 A 的第 i 列中的元素之和为 Ci,A 的第 j 行中的元素之和为 Rj.

我尝试使用贪心算法进行填充:从左到右填充 1 并递减 Ci,并对每一行执行此操作。但是,它没有用。 (另外,然后我尝试按降序对行和列进行排序但仍然没有用)

这可以使用最大流量来解决。 LightOJ, and my code for reference

上有一个类似的(更难的版本)问题

这是解决方案。

我们将首先创建一个二分图。设行数为 no_rows,列数为 no_cols.

现在创建 no_rows + no_cols 个节点。在左侧排列第一个 no_rows 个节点(这将构成我们的二分图的一个 "partite")。让我们将这些节点编号为 l1, l2, ..., lno_row.

同样将最后的no_cols个节点排列在右边(这将形成第二个"partite")。让我们将它们编号为 r1, r2, ... , rno_cols.

现在为所有 1 <= i <= no_rowslirj 添加边 1 <= j <= no_cols,从左到右,容量为1。

现在创建一个源(S) 和一个汇(T)。添加从源到左侧每个顶点的单位容量边。

类似地将单位容量的边从右侧的每个顶点定向到汇点。

现在只需找到该图中的最大流量。现在,如果在某些 li 和某些 rj 之间存在流,则意味着单元格 (i, j) 将具有 1,否则将具有 0。

注意:要确保甚至存在这样的二元矩阵,请确保每个 (S, l) 边和 (r, T) 边都被完全填充。


编辑:这是 Dinic 在 C++ 中的实现 ideone


编辑 2:将源连接到任何 li 的边的容量为 Ri(其中 R 是指示行总和的给定输入数组)。类似地,连接 ri 和下沉 T 的边的容量是 Ci(其中 C 是输入中给出的数组,指示列总和)