# Queries to find the count of connected Non-Empty Cells in a Matrix with updates

• Last Updated : 10 Jun, 2021

Given a boolean matrix mat[][] consisting of N rows and M columns, initially filled with 0‘s(empty cells), an integer K and queries Q[][] of the type {X, Y}, the task is to replace mat[X][Y] = 1(non-empty cells) and count the number of connected non-empty cells from the given matrix.
Examples:

Input: N = 3, M = 3, K = 4, Q[][] = {{0, 0}, {1, 1}, {1, 0}, {1, 2}}
Output: 1 2 1 1
Explanation:
Initially, mat[][] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
Query 1: mat[][] = {{1, 0, 0}, {0, 0, 0}, {0, 0, 0}}, Count = 1
Query 1: mat[][] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 0}}, Count = 2
Query 1: mat[][] = {{1, 0, 0}, {1, 1, 0}, {0, 0, 0}}, Count = 1
Query 1: mat[][] = {{1, 0, 0}, {1, 1, 1}, {0, 0, 0}}, Count = 1
Input: N = 2, M = 2, K = 2, Q[][] = {{0, 0}, {0, 1}}
Output : 1 1

Approach:
The problem can be solved using Disjoint Set Data Structure. Follow the steps below to solve the problem:

• Since, initially, there are no 1‘s in the matrix, count = 0.
• Transform the two-dimension problem into the classic Union-find, by performing a linear mapping index = X * M + Y, where M is the column length.
• After setting an index in each query, increment count.
• If a non-empty cell is present in any of the 4 adjacent cells:
• Perform Union operation for the current index and adjacent cell(connecting two Sets).
• Decrement count as two Sets are connected.

Below is the implementation of the above approach:

## C++

 `// C++ program to implement` `// the above approach` `#include ` `using` `namespace` `std;`   `// Count of connected cells` `int` `ctr = 0;`   `// Function to return the representative` `// of the Set to which x belongs` `int` `find(vector<``int``>& parent, ``int` `x)` `{`   `    ``// If x is parent of itself` `    ``if` `(parent[x] == x)`   `        ``// x is representative` `        ``// of the Set` `        ``return` `x;`   `    ``// Otherwise` `    ``parent[x] = find(parent, parent[x]);`   `    ``// Path Compression` `    ``return` `parent[x];` `}`   `// Unites the set that includes` `// x and the set that includes y` `void` `setUnion(vector<``int``>& parent,` `              ``vector<``int``>& rank, ``int` `x, ``int` `y)` `{` `    ``// Find the representatives(or the` `    ``// root nodes) for x an y` `    ``int` `parentx = find(parent, x);` `    ``int` `parenty = find(parent, y);`   `    ``// If both are in the same set` `    ``if` `(parenty == parentx)` `        ``return``;`   `    ``// Decrement count` `    ``ctr--;`   `    ``// If x's rank is less than y's rank` `    ``if` `(rank[parentx] < rank[parenty]) {` `        ``parent[parentx] = parenty;` `    ``}`   `    ``// Otherwise` `    ``else` `if` `(rank[parentx] > rank[parenty]) {` `        ``parent[parenty] = parentx;` `    ``}` `    ``else` `{`   `        ``// Then move x under y (doesn't matter` `        ``// which one goes where)` `        ``parent[parentx] = parenty;`   `        ``// And increment the result tree's` `        ``// rank by 1` `        ``rank[parenty]++;` `    ``}` `}`   `// Function to count the number of` `// connected cells in the matrix` `vector<``int``> solve(``int` `n, ``int` `m,` `                  ``vector >& query)` `{`   `    ``// Store result for queries` `    ``vector<``int``> result(query.size());`   `    ``// Store representative of` `    ``// each element` `    ``vector<``int``> parent(n * m);`   `    ``// Initially, all elements` `    ``// are in their own set` `    ``for` `(``int` `i = 0; i < n * m; i++)` `        ``parent[i] = i;`   `    ``// Stores the rank(depth) of each node` `    ``vector<``int``> rank(n * m, 1);`   `    ``vector<``bool``> grid(n * m, 0);`   `    ``for` `(``int` `i = 0; i < query.size(); i++) {`   `        ``int` `x = query[i].first;` `        ``int` `y = query[i].second;`   `        ``// If the grid[x*m + y] is already` `        ``// set, store the result` `        ``if` `(grid[m * x + y] == 1) {` `            ``result[i] = ctr;` `            ``continue``;` `        ``}`   `        ``// Set grid[x*m + y] to 1` `        ``grid[m * x + y] = 1;`   `        ``// Increment count.` `        ``ctr++;`   `        ``// Check for all adjacent cells` `        ``// to do a Union with neighbour's` `        ``// set if neighbour is also 1` `        ``if` `(x > 0 and grid[m * (x - 1) + y] == 1)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x - 1) + y);`   `        ``if` `(y > 0 and grid[m * (x) + y - 1] == 1)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x) + y - 1);`   `        ``if` `(x < n - 1 and grid[m * (x + 1) + y] == 1)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x + 1) + y);`   `        ``if` `(y < m - 1 and grid[m * (x) + y + 1] == 1)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x) + y + 1);`   `        ``// Store result.` `        ``result[i] = ctr;` `    ``}` `    ``return` `result;` `}`   `// Driver Code` `int` `main()` `{` `    ``int` `N = 3, M = 3, K = 4;`   `    ``vector > query` `        ``= { { 0, 0 },` `            ``{ 1, 1 },` `            ``{ 1, 0 },` `            ``{ 1, 2 } };` `    ``vector<``int``> result = solve(N, M, query);`   `    ``for` `(``int` `i = 0; i < K; i++)` `        ``cout << result[i] << ``" "``;` `}`

## Java

 `// Java program to implement` `// the above approach` `import` `java.util.*;`   `class` `GFG{`   `// Count of connected cells` `static` `int` `ctr = ``0``;`   `// Function to return the representative` `// of the Set to which x belongs` `static` `int` `find(``int` `[]parent, ``int` `x)` `{` `    `  `    ``// If x is parent of itself` `    ``if` `(parent[x] == x)`   `        ``// x is representative` `        ``// of the Set` `        ``return` `x;`   `    ``// Otherwise` `    ``parent[x] = find(parent, parent[x]);`   `    ``// Path Compression` `    ``return` `parent[x];` `}`   `// Unites the set that includes` `// x and the set that includes y` `static` `void` `setUnion(``int``[] parent,` `                     ``int``[] rank, ``int` `x, ``int` `y)` `{` `    `  `    ``// Find the representatives(or the` `    ``// root nodes) for x an y` `    ``int` `parentx = find(parent, x);` `    ``int` `parenty = find(parent, y);`   `    ``// If both are in the same set` `    ``if` `(parenty == parentx)` `        ``return``;`   `    ``// Decrement count` `    ``ctr--;`   `    ``// If x's rank is less than y's rank` `    ``if` `(rank[parentx] < rank[parenty])` `    ``{` `        ``parent[parentx] = parenty;` `    ``}`   `    ``// Otherwise` `    ``else` `if` `(rank[parentx] > rank[parenty])` `    ``{` `        ``parent[parenty] = parentx;` `    ``}` `    ``else` `    ``{` `        `  `        ``// Then move x under y (doesn't matter` `        ``// which one goes where)` `        ``parent[parentx] = parenty;`   `        ``// And increment the result tree's` `        ``// rank by 1` `        ``rank[parenty]++;` `    ``}` `}`   `// Function to count the number of` `// connected cells in the matrix` `static` `int` `[] solve(``int` `n, ``int` `m,` `                    ``int` `[][]query)` `{` `    `  `    ``// Store result for queries` `    ``int` `[]result = ``new` `int``[query.length];` `    `  `    ``// Store representative of` `    ``// each element` `    ``int` `[]parent = ``new` `int``[n * m];`   `    ``// Initially, all elements` `    ``// are in their own set` `    ``for``(``int` `i = ``0``; i < n * m; i++)` `        ``parent[i] = i;`   `    ``// Stores the rank(depth) of each node` `    ``int` `[]rank = ``new` `int``[n * m];` `    ``Arrays.fill(rank, ``1``);` `    `  `    ``boolean` `[]grid = ``new` `boolean``[n * m];`   `    ``for``(``int` `i = ``0``; i < query.length; i++)` `    ``{` `        ``int` `x = query[i][``0``];` `        ``int` `y = query[i][``1``];`   `        ``// If the grid[x*m + y] is already` `        ``// set, store the result` `        ``if` `(grid[m * x + y] == ``true``)` `        ``{` `            ``result[i] = ctr;` `            ``continue``;` `        ``}`   `        ``// Set grid[x*m + y] to 1` `        ``grid[m * x + y] = ``true``;`   `        ``// Increment count.` `        ``ctr++;`   `        ``// Check for all adjacent cells` `        ``// to do a Union with neighbour's` `        ``// set if neighbour is also 1` `        ``if` `(x > ``0` `&& grid[m * (x - ``1``) + y] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x - ``1``) + y);`   `        ``if` `(y > ``0` `&& grid[m * (x) + y - ``1``] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x) + y - ``1``);`   `        ``if` `(x < n - ``1` `&& grid[m * (x + ``1``) + y] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x + ``1``) + y);`   `        ``if` `(y < m - ``1` `&& grid[m * (x) + y + ``1``] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x) + y + ``1``);`   `        ``// Store result.` `        ``result[i] = ctr;` `    ``}` `    ``return` `result;` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    ``int` `N = ``3``, M = ``3``, K = ``4``;`   `    ``int` `[][]query = { { ``0``, ``0` `},` `                      ``{ ``1``, ``1` `},` `                      ``{ ``1``, ``0` `},` `                      ``{ ``1``, ``2` `} };` `    ``int``[] result = solve(N, M, query);`   `    ``for``(``int` `i = ``0``; i < K; i++)` `        ``System.out.print(result[i] + ``" "``);` `}` `}`   `// This code is contributed by Amit Katiyar`

## Python3

 `# Python 3 program to implement` `# the above approach`   `# Count of connected cells` `ctr ``=` `0`   `# Function to return the ` `# representative of the Set ` `# to which x belongs` `def` `find(parent, x):`   `    ``# If x is parent of itself` `    ``if` `(parent[x] ``=``=` `x):`   `        ``# x is representative` `        ``# of the Set` `        ``return` `x`   `    ``# Otherwise` `    ``parent[x] ``=` `find(parent, ` `                     ``parent[x])`   `    ``# Path Compression` `    ``return` `parent[x]`   `# Unites the set that ` `# includes x and the ` `# set that includes y` `def` `setUnion(parent,` `             ``rank, x, y):`   `    ``global` `ctr` `    `  `    ``# Find the representatives` `    ``# (or the root nodes) for x an y` `    ``parentx ``=` `find(parent, x)` `    ``parenty ``=` `find(parent, y)`   `    ``# If both are in the same set` `    ``if` `(parenty ``=``=` `parentx):` `        ``return`   `    ``# Decrement count` `    ``ctr ``-``=` `1`   `    ``# If x's rank is less than y's rank` `    ``if` `(rank[parentx] < rank[parenty]):` `        ``parent[parentx] ``=` `parenty` `   `  `    ``# Otherwise` `    ``elif` `(rank[parentx] > rank[parenty]):` `        ``parent[parenty] ``=` `parentx` `    `  `    ``else``:`   `        ``# Then move x under y ` `        ``# (doesn't matter which ` `        ``# one goes where)` `        ``parent[parentx] ``=` `parenty`   `        ``# And increment the result ` `        ``# tree's rank by 1` `        ``rank[parenty] ``+``=` `1` `  `  `# Function to count the number of` `# connected cells in the matrix` `def` `solve(n, m, query):`   `    ``global` `ctr ` `    `  `    ``# Store result for queries` `    ``result ``=` `[``0``] ``*` `len``(query)`   `    ``# Store representative of` `    ``# each element` `    ``parent ``=` `[``0``] ``*` `(n ``*` `m)`   `    ``# Initially, all elements` `    ``# are in their own set` `    ``for` `i ``in` `range` `(n ``*` `m):` `        ``parent[i] ``=` `i`   `    ``# Stores the rank(depth) ` `    ``# of each node` `    ``rank ``=` `[``1``] ``*` `(n ``*` `m)` `  `  `    ``grid ``=` `[``0``] ``*` `(n ``*` `m)`   `    ``for`  `i ``in` `range` `(``len``( query)):` `        ``x ``=` `query[i][``0``]` `        ``y ``=` `query[i][``1``]`   `        ``# If the grid[x*m + y] is already` `        ``# set, store the result` `        ``if` `(grid[m ``*` `x ``+` `y] ``=``=` `1``):` `            ``result[i] ``=` `ctr` `            ``continue` `       `  `        ``# Set grid[x*m + y] to 1` `        ``grid[m ``*` `x ``+` `y] ``=` `1`   `        ``# Increment count.` `        ``ctr ``+``=` `1`   `        ``# Check for all adjacent cells` `        ``# to do a Union with neighbour's` `        ``# set if neighbour is also 1` `        ``if` `(x > ``0` `and` `            ``grid[m ``*` `(x ``-` `1``) ``+` `y] ``=``=` `1``):` `            ``setUnion(parent, rank,` `                     ``m ``*` `x ``+` `y, ` `                     ``m ``*` `(x ``-` `1``) ``+` `y)`   `        ``if` `(y > ``0` `and` `            ``grid[m ``*` `(x) ``+` `y ``-` `1``] ``=``=` `1``):` `            ``setUnion(parent, rank,` `                     ``m ``*` `x ``+` `y, ` `                     ``m ``*` `(x) ``+` `y ``-` `1``)`   `        ``if` `(x < n ``-` `1` `and` `            ``grid[m ``*` `(x ``+` `1``) ``+` `y] ``=``=` `1``):` `            ``setUnion(parent, rank,` `                     ``m ``*` `x ``+` `y, ` `                     ``m ``*` `(x ``+` `1``) ``+` `y)`   `        ``if` `(y < m ``-` `1` `and` `            ``grid[m ``*` `(x) ``+` `y ``+` `1``] ``=``=` `1``):` `            ``setUnion(parent, rank,` `                     ``m ``*` `x ``+` `y, ` `                     ``m ``*` `(x) ``+` `y ``+` `1``)`   `        ``# Store result.` `        ``result[i] ``=` `ctr` `    ``return` `result`   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:` `      `  `    ``N ``=` `3` `    ``M ``=` `3` `    ``K ``=` `4` `    ``query ``=` `[[``0``, ``0``],` `             ``[``1``, ``1``],` `             ``[``1``, ``0``],` `             ``[``1``, ``2``]]` `    ``result ``=` `solve(N, M, query)` `    ``for` `i ``in` `range` `(K):` `        ``print` `(result[i], end ``=` `" "``)` `        `  `# This code is contributed by Chitranayal`

## C#

 `// C# program to implement` `// the above approach` `using` `System;` `class` `GFG{`   `// Count of connected cells` `static` `int` `ctr = 0;`   `// Function to return the representative` `// of the Set to which x belongs` `static` `int` `find(``int` `[]parent, ``int` `x)` `{` `    `  `    ``// If x is parent of itself` `    ``if` `(parent[x] == x)`   `        ``// x is representative` `        ``// of the Set` `        ``return` `x;`   `    ``// Otherwise` `    ``parent[x] = find(parent, parent[x]);`   `    ``// Path Compression` `    ``return` `parent[x];` `}`   `// Unites the set that includes` `// x and the set that includes y` `static` `void` `setUnion(``int``[] parent,` `                     ``int``[] rank, ` `                     ``int` `x, ``int` `y)` `{` `    `  `    ``// Find the representatives(or the` `    ``// root nodes) for x an y` `    ``int` `parentx = find(parent, x);` `    ``int` `parenty = find(parent, y);`   `    ``// If both are in the same set` `    ``if` `(parenty == parentx)` `        ``return``;`   `    ``// Decrement count` `    ``ctr--;`   `    ``// If x's rank is less than y's rank` `    ``if` `(rank[parentx] < rank[parenty])` `    ``{` `        ``parent[parentx] = parenty;` `    ``}`   `    ``// Otherwise` `    ``else` `if` `(rank[parentx] > rank[parenty])` `    ``{` `        ``parent[parenty] = parentx;` `    ``}` `    ``else` `    ``{` `        `  `        ``// Then move x under y (doesn't matter` `        ``// which one goes where)` `        ``parent[parentx] = parenty;`   `        ``// And increment the result tree's` `        ``// rank by 1` `        ``rank[parenty]++;` `    ``}` `}`   `// Function to count the number of` `// connected cells in the matrix` `static` `int` `[] solve(``int` `n, ``int` `m,` `                    ``int` `[,]query)` `{` `    `  `    ``// Store result for queries` `    ``int` `[]result = ``new` `int``[query.Length];` `    `  `    ``// Store representative of` `    ``// each element` `    ``int` `[]parent = ``new` `int``[n * m];`   `    ``// Initially, all elements` `    ``// are in their own set` `    ``for``(``int` `i = 0; i < n * m; i++)` `        ``parent[i] = i;`   `    ``// Stores the rank(depth) of each node` `    ``int` `[]rank = ``new` `int``[n * m];` `    ``for``(``int` `i = 0; i < rank.Length; i++)` `        ``rank[i] = 1;` `    ``bool` `[]grid = ``new` `bool``[n * m];`   `    ``for``(``int` `i = 0; i < query.GetLength(0); i++)` `    ``{` `        ``int` `x = query[i, 0];` `        ``int` `y = query[i, 1];`   `        ``// If the grid[x*m + y] is already` `        ``// set, store the result` `        ``if` `(grid[m * x + y] == ``true``)` `        ``{` `            ``result[i] = ctr;` `            ``continue``;` `        ``}`   `        ``// Set grid[x*m + y] to 1` `        ``grid[m * x + y] = ``true``;`   `        ``// Increment count.` `        ``ctr++;`   `        ``// Check for all adjacent cells` `        ``// to do a Union with neighbour's` `        ``// set if neighbour is also 1` `        ``if` `(x > 0 && grid[m * (x - 1) + y] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x - 1) + y);`   `        ``if` `(y > 0 && grid[m * (x) + y - 1] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x) + y - 1);`   `        ``if` `(x < n - 1 && grid[m * (x + 1) + y] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x + 1) + y);`   `        ``if` `(y < m - 1 && grid[m * (x) + y + 1] == ``true``)` `            ``setUnion(parent, rank,` `                     ``m * x + y, m * (x) + y + 1);`   `        ``// Store result.` `        ``result[i] = ctr;` `    ``}` `    ``return` `result;` `}`   `// Driver Code` `public` `static` `void` `Main(String[] args)` `{` `    ``int` `N = 3, M = 3, K = 4;`   `    ``int` `[,]query = {{ 0, 0 }, { 1, 1 },` `                    ``{ 1, 0 }, { 1, 2 }};` `    ``int``[] result = solve(N, M, query);`   `    ``for``(``int` `i = 0; i < K; i++)` `        ``Console.Write(result[i] + ``" "``);` `}` `}`   `// This code is contributed by sapnasingh4991`

## Javascript

 ``

Output:

`1 2 1 1`

Time Complexity: O(N * M * sizeof(Q))
Auxiliary Space: O(N*M)

My Personal Notes arrow_drop_up
Recommended Articles
Page :