Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Minimum Cost Path with Left, Right, Bottom and Up moves allowed

  • Difficulty Level : Hard
  • Last Updated : 11 Nov, 2021

Given a two dimensional grid, each cell of which contains integer cost which represents a cost to traverse through that cell, we need to find a path from top left cell to bottom right cell by which total cost incurred is minimum.
Note : It is assumed that negative cost cycles do not exist in input matrix.
This problem is extension of below problem.
Min Cost Path with right and bottom moves allowed.
In previous problem only going right and bottom was allowed but in this problem we are allowed to go bottom, up, right and left i.e. in all 4 direction.
Examples:

A cost grid is given in below diagram, minimum 
cost to reach bottom right from top left 
is 327 (= 31 + 10 + 13 + 47 + 65 + 12 + 18 + 
6 + 33 + 11 + 20 + 41 + 20)

The chosen least cost path is shown in green.

It is not possible to solve this problem using dynamic programming similar to previous problem because here current state depends not only on right and bottom cells but also on left and upper cells. We solve this problem using dijkstra’s algorithm. Each cell of grid represents a vertex and neighbor cells adjacent vertices. We do not make an explicit graph from these cells instead we will use matrix as it is in our dijkstra’s algorithm. 
In below code Dijkstra’ algorithm’s implementation is used. The code implemented below is changed to cope with matrix represented implicit graph. Please also see use of dx and dy arrays in below code, these arrays are taken for simplifying the process of visiting neighbor vertices of each cell.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

C++




// C++ program to get least cost path in a grid from
// top-left to bottom-right
#include <bits/stdc++.h>
using namespace std;
 
#define ROW 5
#define COL 5
 
// structure for information of each cell
struct cell
{
    int x, y;
    int distance;
    cell(int x, int y, int distance) :
        x(x), y(y), distance(distance) {}
};
 
// Utility method for comparing two cells
bool operator<(const cell& a, const cell& b)
{
    if (a.distance == b.distance)
    {
        if (a.x != b.x)
            return (a.x < b.x);
        else
            return (a.y < b.y);
    }
    return (a.distance < b.distance);
}
 
// Utility method to check whether a point is
// inside the grid or not
bool isInsideGrid(int i, int j)
{
    return (i >= 0 && i < ROW && j >= 0 && j < COL);
}
 
// Method returns minimum cost to reach bottom
// right from top left
int shortest(int grid[ROW][COL], int row, int col)
{
    int dis[row][col];
 
    // initializing distance array by INT_MAX
    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            dis[i][j] = INT_MAX;
 
    // direction arrays for simplification of getting
    // neighbour
    int dx[] = {-1, 0, 1, 0};
    int dy[] = {0, 1, 0, -1};
 
    set<cell> st;
 
    // insert (0, 0) cell with 0 distance
    st.insert(cell(0, 0, 0));
 
    // initialize distance of (0, 0) with its grid value
    dis[0][0] = grid[0][0];
 
    // loop for standard dijkstra's algorithm
    while (!st.empty())
    {
        // get the cell with minimum distance and delete
        // it from the set
        cell k = *st.begin();
        st.erase(st.begin());
 
        // looping through all neighbours
        for (int i = 0; i < 4; i++)
        {
            int x = k.x + dx[i];
            int y = k.y + dy[i];
 
            // if not inside boundary, ignore them
            if (!isInsideGrid(x, y))
                continue;
 
            // If distance from current cell is smaller, then
            // update distance of neighbour cell
            if (dis[x][y] > dis[k.x][k.y] + grid[x][y])
            {
                // If cell is already there in set, then
                // remove its previous entry
                if (dis[x][y] != INT_MAX)
                    st.erase(st.find(cell(x, y, dis[x][y])));
 
                // update the distance and insert new updated
                // cell in set
                dis[x][y] = dis[k.x][k.y] + grid[x][y];
                st.insert(cell(x, y, dis[x][y]));
            }
        }
    }
 
    // uncomment below code to print distance
    // of each cell from (0, 0)
    /*
    for (int i = 0; i < row; i++, cout << endl)
        for (int j = 0; j < col; j++)
            cout << dis[i][j] << " ";
    */
    // dis[row - 1][col - 1] will represent final
    // distance of bottom right cell from top left cell
    return dis[row - 1][col - 1];
}
 
// Driver code to test above methods
int main()
{
    int grid[ROW][COL] =
    {
        31, 100, 65, 12, 18,
        10, 13, 47, 157, 6,
        100, 113, 174, 11, 33,
        88, 124, 41, 20, 140,
        99, 32, 111, 41, 20
    };
 
    cout << shortest(grid, ROW, COL) << endl;
    return 0;
}

Java




// Java program to get least cost path
// in a grid from top-left to bottom-right
import java.io.*;
import java.util.*;
 
class GFG{
     
static int[] dx = { -1, 0, 1, 0 };
static int[] dy = { 0, 1, 0, -1 };
static int ROW = 5;
static int COL = 5;
 
// Custom class for representing
// row-index, column-index &
// distance of each cell
static class Cell
{
    int x;
    int y;
    int distance;
     
    Cell(int x, int y, int distance)
    {
        this.x = x;
        this.y = y;
        this.distance = distance;
    }
}
 
// Custom comparator for inserting cells
// into Priority Queue
static class distanceComparator
  implements Comparator<Cell>
{
    public int compare(Cell a, Cell b)
    {
        if (a.distance < b.distance)
        {
            return -1;
        }
        else if (a.distance > b.distance)
        {
            return 1;
        }
        else {return 0;}
    }
}
 
// Utility method to check whether current
// cell is inside grid or not
static boolean isInsideGrid(int i, int j)
{
    return (i >= 0 && i < ROW &&
            j >= 0 && j < COL);
}
 
// Method to return shortest path from
// top-corner to bottom-corner in 2D grid
static int shortestPath(int[][] grid, int row,
                                      int col)
{
    int[][] dist = new int[row][col];
     
    // Initializing distance array by INT_MAX
    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < col; j++)
        {
            dist[i][j] = Integer.MAX_VALUE;
        }
    }
     
    // Initialized source distance as
    // initial grid position value
    dist[0][0] = grid[0][0];
     
    PriorityQueue<Cell> pq = new PriorityQueue<Cell>(
                  row * col, new distanceComparator());
                   
    // Insert source cell to priority queue
    pq.add(new Cell(0, 0, dist[0][0]));
    while (!pq.isEmpty())
    {
        Cell curr = pq.poll();
        for(int i = 0; i < 4; i++)
        {
            int rows = curr.x + dx[i];
            int cols = curr.y + dy[i];
             
            if (isInsideGrid(rows, cols))
            {
                if (dist[rows][cols] >
                    dist[curr.x][curr.y] +
                    grid[rows][cols])
                {
                     
                    // If Cell is already been reached once,
                    // remove it from priority queue
                    if (dist[rows][cols] != Integer.MAX_VALUE)
                    {
                        Cell adj = new Cell(rows, cols,
                                       dist[rows][cols]);
                                        
                        pq.remove(adj);
                    }
                     
                    // Insert cell with updated distance
                    dist[rows][cols] = dist[curr.x][curr.y] +
                                       grid[rows][cols];
                                        
                    pq.add(new Cell(rows, cols,
                               dist[rows][cols]));
                }
            }
        }
    }
    return dist[row - 1][col - 1];
}
 
// Driver code
public static void main(String[] args)
throws IOException
{
    int[][] grid = { { 31, 100, 65, 12, 18 },
                     { 10, 13, 47, 157, 6 },
                     { 100, 113, 174, 11, 33 },
                     { 88, 124, 41, 20, 140 },
                     { 99, 32, 111, 41, 20 } };
                      
    System.out.println(shortestPath(grid, ROW, COL));
}
}
 
// This code is contributed by jigyansu

Javascript




<script>
  
// Javascript program to get least cost path in a grid from
// top-left to bottom-right
var ROW = 5
var COL = 5
 
// structure for information of each cell
class cell
{
    constructor(x, y, distance)
    {
        this.x = x;
        this.y = y;
        this.distance = distance;
    }
};
 
 
// Utility method to check whether a point is
// inside the grid or not
function isInsideGrid(i, j)
{
    return (i >= 0 && i < ROW && j >= 0 && j < COL);
}
 
// Method returns minimum cost to reach bottom
// right from top left
function shortest(grid, row, col)
{
    var dis = Array.from(Array(row), ()=>Array(col).fill(0));
 
    // initializing distance array by INT_MAX
    for (var i = 0; i < row; i++)
        for (var j = 0; j < col; j++)
            dis[i][j] = 1000000000;
 
    // direction arrays for simplification of getting
    // neighbour
    var dx = [-1, 0, 1, 0];
    var dy = [0, 1, 0, -1];
 
    var st = [];
 
    // insert (0, 0) cell with 0 distance
    st.push(new cell(0, 0, 0));
 
    // initialize distance of (0, 0) with its grid value
    dis[0][0] = grid[0][0];
 
    // loop for standard dijkstra's algorithm
    while (st.length!=0)
    {
        // get the cell with minimum distance and delete
        // it from the set
        var k = st[0];
        st.shift();
 
        // looping through all neighbours
        for (var i = 0; i < 4; i++)
        {
            var x = k.x + dx[i];
            var y = k.y + dy[i];
 
            // if not inside boundary, ignore them
            if (!isInsideGrid(x, y))
                continue;
 
            // If distance from current cell is smaller, then
            // update distance of neighbour cell
            if (dis[x][y] > dis[k.x][k.y] + grid[x][y])
            {
                // update the distance and insert new updated
                // cell in set
                dis[x][y] = dis[k.x][k.y] + grid[x][y];
                st.push(new cell(x, y, dis[x][y]));
            }
        }
        st.sort((a,b)=>{
            if (a.distance == b.distance)
    {
        if (a.x != b.x)
            return (a.x - b.x);
        else
            return (a.y - b.y);
    }
    return (a.distance - b.distance);
        });
    }
 
    // uncomment below code to print distance
    // of each cell from (0, 0)
    /*
    for (int i = 0; i < row; i++, cout << endl)
        for (int j = 0; j < col; j++)
            cout << dis[i][j] << " ";
    */
    // dis[row - 1][col - 1] will represent final
    // distance of bottom right cell from top left cell
    return dis[row - 1][col - 1];
}
 
// Driver code to test above methods
var grid =
[
    [31, 100, 65, 12, 18],
    [10, 13, 47, 157, 6],
    [100, 113, 174, 11, 33],
    [88, 124, 41, 20, 140],
    [99, 32, 111, 41, 20]
];
document.write(shortest(grid, ROW, COL));
 
// This code is contributed by rutvik_56.
 
</script>

Output:

327

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
 




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!