生成二进制矩阵的算法
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_rows
和 li
和 rj
添加边
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
是输入中给出的数组,指示列总和)
给定两个输入数组 [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_rows
和 li
和 rj
添加边
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
是输入中给出的数组,指示列总和)