algorithmgreedybinary-matrix

Algorithm to generate a binary matrix


Given two input arrays [R1, ..., Rn] and [C1, ..., Cn]. We want to create a binary matrix A (of size-nxn) such that the sum of elements in column i of A be Ci and the sum of elements in row j of A be Rj.

I tried to fill using greedy algorithm : fill 1's from left to right and decrement Ci's and do this for each row. But, it didn't work. (Also, then I tried to sort rows and columns in decreasing order but still didn't work)


Solution

  • This can be solved using Maximum Flows. A similar (harder version of this) problem is available on LightOJ, and my code for reference

    Here is the solution.

    We will first create a bipartite graph. Let the number of rows be no_rows and number of columns be no_cols.

    Now create no_rows + no_cols nodes. Arrange the first no_rows nodes in the left (which will form one "partite" of our bipartite graph). Lets number these nodes as l1, l2, ..., lno_row.

    Similarly arrange the last no_cols nodes in the right (which will form the second "partite"). Lets number these as r1, r2, ... , rno_cols.

    Now add edges between each li and rj for all 1 <= i <= no_rows and 1 <= j <= no_cols, oriented from the left to the right, with a capacity of 1.

    Now create a source(S) and a sink(T). Add edge of unit capacity oriented from source to each vertex on the left.

    Similarly add edges of unit capacity oriented from each vertex on the right, to the sink.

    Now just find the Maximum Flow in this graph. Now if there exists a flow between some li and some rj, that implies that the cell (i, j) will have 1, otherwise it will have 0.

    Note: To ensure that there even exists such a binary matrix, make sure that each of the (S, l) edges and (r, T) edges are completely filled.


    Edit: Here is an implementation of Dinic in C++ ideone


    Edit 2: The capacity of the edge connecting the source to any li is Ri (where R is the given input array indicating row sums). Similarly the capacity of the edge connecting ri to sink T is Ci (where C is the array given in input indicating column sums)