【圖論】A031_LC_使網格圖至少有一條有效路徑的最小代價(最短路變形)

一、Problem

Given a m x n grid. Each cell of the grid has a sign pointing to the next cell you should visit if you are currently in this cell. The sign of grid[i][j] can be:
1 which means go to the cell to the right. (i.e go from grid[i][j] to grid[i][j + 1])
2 which means go to the cell to the left. (i.e go from grid[i][j] to grid[i][j - 1])
3 which means go to the lower cell. (i.e go from grid[i][j] to grid[i + 1][j])
4 which means go to the upper cell. (i.e go from grid[i][j] to grid[i - 1][j])
Notice that there could be some invalid signs on the cells of the grid which points outside the grid.

You will initially start at the upper left cell (0,0). A valid path in the grid is a path which starts from the upper left cell (0,0) and ends at the bottom-right cell (m - 1, n - 1) following the signs on the grid. The valid path doesn’t have to be the shortest.

You can modify the sign on a cell with cost = 1. You can modify the sign on a cell one time only.

Return the minimum cost to make the grid have at least one valid path.
Alt

Input: grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
Output: 3
Explanation: You will start at point (0, 0).
The path to (3, 3) is as follows. (0, 0) --> (0, 1) --> (0, 2) --> (0, 3) 
change the arrow to down with cost = 1 --> (1, 3) --> (1, 2) --> (1, 1) --> (1, 0) 
change the arrow to down with cost = 1 --> (2, 0) --> (2, 1) --> (2, 2) --> (2, 3) 
change the arrow to down with cost = 1 --> (3, 3)
The total cost = 3.

二、Solution

方法一:dijkstra

  • 限制條件是改變網格中的原有方向,則花費 cost 會加 1
  • 轉化爲圖論問題會簡化很多:把每個格子看做是一個結點,結點之間連上不超過 4 條邊(上下左右)
  • 如果當前方向與輪迴方向不同則將花費加 1,然後在添加到隊列中。

未知錯誤:不知道爲什麼總是求不出答案… 哪裏有問題?

class Solution {
    final static int[][] dir = { {1,0},{0,-1},{0,1},{-1,0} };
    int R, C, d[], INF = 0x3f3f3f3f;
    boolean[] seen;
    void dijstra(int[][] g) {
        Queue<Pos> q = new PriorityQueue<>((e1, e2) -> e1.cost - e2.cost);
        q.add(new Pos(0, 0));
        seen[0] = true;
        d[0] = 0;
        while (!q.isEmpty()) {
            Pos t = q.poll();
            int x = t.pos / R, y = t.pos % R;
            for (int k = 0; k < 4; k++) {
                int tx = x + dir[k][0], ty = y + dir[k][1], tp = tx * R + ty;
                if (tx < 0 || tx >= R || ty < 0 || ty >= C || seen[tp])
                    continue;
                int tv = t.cost + (g[x][y] == k+1 ? 0 : 1);
                if (tv < d[tp]) {
                    d[tp] = tv;
                    q.add(new Pos(tp, tv));
                    seen[tp] = true;
                }
            }
        }
    }
    public int minCost(int[][] grid) {
        R = grid.length; C = grid[0].length;
        d = new int[R * C]; seen = new boolean[R * C];
        Arrays.fill(d, INF);
        dijstra(grid);
        // for (int i : d) System.out.print(i);
        return d[R*C-1];
    }
    class Pos {
        int pos, cost;
        Pos(int pos, int cost) {
            this.pos = pos; this.cost = cost;
        }
    }
}

複雜度分析

  • 時間複雜度:O(E×V×log(E+V))O(E × V × log (E+V))
  • 空間複雜度:O(E+V)O(E+V)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章