Minimum distance to the corner of a grid from source

Given a binary grid of order r * c and an initial position. The task is to find the minimum distance from the source to get to the any corner of the grid. A move can be made to a cell grid[i][j] only if grid[i][j] = 0 and only left, right, up and down movements are permitted. If no valid path exists then print -1.

Examples:

Input: i = 1, j = 1, grid[][] = {{0, 0, 1}, {0, 0, 0}, {1, 1, 1}}
Output: 2
(1, 1) -> (1, 0) -> (0, 0)

Input: i = 0, j = 0, grid[][] = {{0, 1}, {1, 1}}
Output: 0
Source is already a corner of the grid.



Approach:

  • If source is already any of the corner then print 0.
  • Start traversing the grid starting with source using BFS as :
    • Insert cell position in queue.
    • Pop element from queue and mark it visited.
    • For each valid move adjacent to popped one, insert the cell position into queue.
    • On each move, update the minimum distance of the cell from initial position.
  • After the completion of the BFS, find the minimum distance from source to every corner.
  • Print the minimum among these in the end.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define row 5
#define col 5
  
// Global variables for grid, minDistance and visited array
int minDistance[row + 1][col + 1], visited[row + 1][col + 1];
  
// Queue for BFS
queue<pair<int, int> > que;
  
// Function to find whether the move is valid or not
bool isValid(int grid[][col], int i, int j)
{
    if (i < 0 || j < 0
        || j >= col || i >= row
        || grid[i][j] || visited[i][j])
        return false;
  
    return true;
}
  
// Function to return the minimum distance
// from source to the end of the grid
int minDistance(int grid[][col],
                           int sourceRow, int sourceCol)
{
    // If source is one of the destinations
    if ((sourceCol == 0 && sourceRow == 0)
        || (sourceCol == col - 1 && sourceRow == 0)
        || (sourceCol == 0 && sourceRow == row - 1)
        || (sourceCol == col - 1 && sourceRow == row - 1))
        return 0;
  
    // Set minimum value
    int minFromSource = row * col;
  
    // Precalculate minDistance of each grid with R * C
    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            minDistance[i][j] = row * col;
  
    // Insert source position in queue
    que.push(make_pair(sourceRow, sourceCol));
  
    // Update minimum distance to visit source
    minDistance[sourceRow][sourceCol] = 0;
  
    // Set source to visited
    visited[sourceRow][sourceCol] = 1;
  
    // BFS approach for calculating the minDistance
    // of each cell from source
    while (!que.empty()) {
  
        // Iterate over all four cells adjacent
        // to current cell
        pair<int, int> cell = que.front();
  
        // Initialize position of current cell
        int cellRow = cell.first;
        int cellCol = cell.second;
  
        // Cell below the current cell
        if (isValid(grid, cellRow + 1, cellCol)) {
  
            // Push new cell to the queue
            que.push(make_pair(cellRow + 1, cellCol));
  
            // Update one of its neightbor's distance
            minDistance[cellRow + 1][cellCol]
                = min(minDistance[cellRow + 1][cellCol],
                      minDistance[cellRow][cellCol] + 1);
            visited[cellRow + 1][cellCol] = 1;
        }
  
        // Above the current cell
        if (isValid(grid, cellRow - 1, cellCol)) {
            que.push(make_pair(cellRow - 1, cellCol));
            minDistance[cellRow - 1][cellCol]
                = min(minDistance[cellRow - 1][cellCol],
                      minDistance[cellRow][cellCol] + 1);
            visited[cellRow - 1][cellCol] = 1;
        }
  
        // Right cell
        if (isValid(grid, cellRow, cellCol + 1)) {
            que.push(make_pair(cellRow, cellCol + 1));
            minDistance[cellRow][cellCol + 1]
                = min(minDistance[cellRow][cellCol + 1],
                      minDistance[cellRow][cellCol] + 1);
            visited[cellRow][cellCol + 1] = 1;
        }
  
        // Left cell
        if (isValid(grid, cellRow, cellCol - 1)) {
            que.push(make_pair(cellRow, cellCol - 1));
            minDistance[cellRow][cellCol - 1]
                = min(minDistance[cellRow][cellCol - 1],
                      minDistance[cellRow][cellCol] + 1);
            visited[cellRow][cellCol - 1] = 1;
        }
  
        // Pop the the visited cell
        que.pop();
    }
  
    int i;
  
    // Minimum distance to the corner
    // of the first row, first column
    minFromSource = min(minFromSource,
                        minDistance[0][0]);
  
    // Minimum distance to the corner
    // of the last row, first column
    minFromSource = min(minFromSource,
                        minDistance[row - 1][0]);
  
    // Minimum distance to the corner
    // of the last row, last column
    minFromSource = min(minFromSource,
                        minDistance[row - 1][col - 1]);
  
    // Minimum distance to the corner
    // of the first row, last column
    minFromSource = min(minFromSource,
                        minDistance[0][col - 1]);
  
    // If no path exists
    if (minFromSource == row * col)
        return -1;
  
    // Return the minimum distance
    return minFromSource;
}
  
// Driver code
int main()
{
    int sourceRow = 3, sourceCol = 3;
    int grid[row][col] = { 1, 1, 1, 0, 0,
                           0, 0, 1, 0, 1,
                           0, 0, 1, 0, 1,
                           1, 0, 0, 0, 1,
                           1, 1, 0, 1, 0 };
  
    cout << minDistance(grid, sourceRow, sourceCol);
  
    return 0;
}

chevron_right


Output:

4


My Personal Notes arrow_drop_up

Discovering ways to develop a plane for soaring career goals

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.