# Program to count number of walls required to partition top-left and bottom-right cells in Python

PythonServer Side ProgrammingProgramming

Suppose we have a 2d binary matrix where 0 represents empty cell and 1 represents a wall. We have to find the minimum number cells that need to become walls so that there will be no path between top−left cell and bottom-right cell. We cannot put walls on the top−left cell and the bottom−right cell. We can move only left, right, up and down not diagonally.

So, if the input is like

 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0

then the output will be 2,

 0 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0

To solve this, we will follow these steps −

• R := row count of matrix, C := column count of matrix

• visited := a new set

• tin := a new map, low := a new map

• timer := 0

• bridge_pts := a new set

• par := a new map

• src := a pair (0, 0)

• tgt := a pair (R − 1, C − 1)

• Define a function dfs() . This will take v, parent

• mark v as visited

• par[v] := parent, tin[v] := timer, low[v] := timer

• timer := timer + 1

• children := 0

• for each to neighbors of v, do

• if to is same as parent, then

• go for next iteration

• if to is visited, then

• low[v] := minimum of low[v] and tin[to]

• otherwise,

• dfs(to, v)

• low[v] := minimum of low[v] and low[to]

• if low[to] >= tin[v] and parent is not null, then

• children := children + 1

• if parent is null and children > 1, then

• Define a function bfs() . This will take root

• Q := a double ended queue with a list with single element root

• visited := a new set and initially insert root

• while Q is not empty, do

• v := last element of Q, then delete last element from Q

• if v is same as tgt, then

• return True

• for each w in the neighbors of v, do

• if w is not visited, then

• mark w as visited

• insert w at the left of Q

• return False

• From the main method do the following −

• dfs(src, null)

• if tgt is not in par, then

• return 0

• for each pair (i, j) in bridge_pts, do

• matrix[i, j] := 1

• if bfs(src) is true, then

• return 2

• return 1

Let us see the following implementation to get better understanding −

## Example

Live Demo

from collections import deque
class Solution:
def solve(self, matrix):
R = len(matrix)
C = len(matrix)
def get_neighbors(i, j):
for ii, jj in ((i + 1, j), (i− 1, j), (i, j + 1), (i, j − 1)):
if 0 <= ii < R and 0 <= jj < C and matrix[ii][jj] == 0:
yield ii, jj
visited = set()
tin = {}
low = {}
timer = 0
bridge_pts = set()
par = {}
src = (0, 0)
tgt = (R− 1, C− 1)
def dfs(v, parent):
nonlocal timer
par[v] = parent
tin[v] = timer
low[v] = timer
timer += 1
children = 0
for to in get_neighbors(*v):
if to == parent:
continue
if to in visited:
low[v] = min(low[v], tin[to])
else:
dfs(to, v)
low[v] = min(low[v], low[to])
if low[to] >= tin[v] and parent is not None:
children += 1
if parent is None and children > 1:
def bfs(root):
Q = deque([root])
visited = set([root])
while Q:
v = Q.pop()
if v == tgt:
return True
for w in get_neighbors(*v):
if w not in visited:
Q.appendleft(w)
return False
dfs(src, None)
if tgt not in par:
return 0
for i, j in bridge_pts:
matrix[i][j] = 1
if bfs(src):
return 2
return 1
ob = Solution()
matrix = [
[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
]
print(ob.solve(matrix))

## Input

[
[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
]

## Output

2