leetcode 1368 使图格网至少有一条有效路径的最小代价

https://leetcode-cn.com/problems/minimum-cost-to-make-at-least-one-valid-path-in-a-grid/

该题可以抽象为从左上角到右上角需要的最小花费, 求最小花费就是求最小路径

其中边权可以抽象为 0 1, 当一个点存在方向时, 权值为 0 没有方向时 权值为 1

01bfs:

​ 就是讲能够到达权值为0的边加入到双端队列的首部, 不能到达权值的边放到双端队列

的尾部, 这样其实在第一次遍历到 右下角的点时 就是最终答案

至于 vis 数组是否需要加上, 其实不需要加, vis防止已经判断点继续回溯,

dis[x][y] + cost < dis[xnxt][ynxt] // 这个判断其实就可以使的即使判断点回溯, 也需要满足权值比先前到达xnxt,ynext的路径花费小,才能够更新, 因此,这道题其实可以用 普通 queue 直接做出来, 只不过需要遍历更多的路径, 01bfs这道题很快,时间复杂度为o(n)
const int dx[5] = {0, 0, 0, 1, -1};
const int dy[5] = {0, 1, -1, 0, 0};
const int inf = 0x3f3f3f3f;
typedef pair<int, int> pir;
class Solution {
public:
    int minCost(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        bool vis[n][m];
        int dis[n][m];
        memset(dis, inf, sizeof(dis));
        deque<pir> pq;
        pq.push_front({0, 0});
        dis[0][0] = 0;
        while(!pq.empty()) {
            pir front = pq.front();
            int x = front.first, y = front.second;
            pq.pop_front();
            if(x == n - 1 && y == m - 1) return dis[x][y];
            for(int i = 1; i <= 4; i++) {
                int xnxt = x + dx[i], ynxt = y + dy[i], cost = grid[x][y] == i ? 0 : 1;
                if(xnxt < 0 || xnxt >= n || ynxt < 0 || ynxt >= m) continue;
                if(dis[x][y] + cost < dis[xnxt][ynxt]) {
                    dis[xnxt][ynxt] = dis[x][y] + cost;
                    if(cost == 0) pq.push_front({xnxt, ynxt});
                    if(cost == 1) pq.push_back({xnxt, ynxt});
                }
            }
        }
        return 0;
    }
};
原文地址:https://www.cnblogs.com/csyxdh/p/12422266.html