1. 程式人生 > 實用技巧 >b_lc_最小體力消耗路徑(bfs/二分/並查集,記低階失誤)

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);
    }
};