b_lc_最小体力消耗路径(bfs/二分/并查集,记低级失误)

一条路径耗费的 体力值 是路径上相邻格子之间 高度差绝对值最大值 决定的。
请你返回从左上角走到右下角的最小 体力消耗值

思路:f[i][j]记录走到(i,j)时的最小体力消耗(注意是途中的最大消耗),可能一个点会过多次(包括终点)
注:如果单纯以abs(g[tx][ty]-g[t.x][t.y]>f[tx][ty])剪枝会错,因为有可能abs(g[tx][ty]-g[t.x][t.y]>f[tx][ty])比f[tx][ty]小,但f[t.x][t.y]比f[tx][ty]大,而这两种情况都是要剪掉

const int N=105, dir[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };
struct node {
    int x,y;
};
class Solution {
public:
    int n,m,f[N][N];
    int bfs(int x, int y, vector<vector<int>>& g) {
        queue<node> q;
        q.push({x,y}), memset(f,0x3f3f3f3f,sizeof f), f[x][y]=0;
        while (!q.empty()) {
            node t=q.front(); q.pop();
            for (int k=0; k<4; k++) {
                int tx=t.x+dir[k][0], ty=t.y+dir[k][1];
                if (tx>=0 && tx<n && ty>=0 && ty<m) {
                    int v=max(f[t.x][t.y], abs(g[tx][ty]-g[t.x][t.y]));
                    if (v>=f[tx][ty]) continue;
                    f[tx][ty]=v;
                    q.push({tx,ty});
                }
            }
        }
        return f[n-1][m-1];
    }   
    int minimumEffortPath(vector<vector<int>>& g) {
        n=g.size(), m=g[0].size();
        return bfs(0,0,g);
    }
};
posted @ 2020-10-25 20:02  童年の波鞋  阅读(126)  评论(0编辑  收藏  举报