力扣1631. 最小体力消耗路径
力扣
[二分广搜或并查集或最短路]最小体力消耗路径
1)二分限定边权的值x
每次搜索,只有小于等于x的值才可以被允许。
class Solution {
public:
vector<vector<int>> g;
int n,m;
int minimumEffortPath(vector<vector<int>>& heights) {
if(!heights.size() || !heights[0].size()) return 0;
n = heights.size();
m = heights[0].size();
g = heights;
int l = 0 ,r = 1e6;
while(l < r){
int mid = l + r >> 1;
if(ck(mid)) r = mid;
else l = mid + 1;
}
return l;
}
bool ck(int x){
queue<pair<int,int>> q;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
q.push({0,0});
//可以用一手状态压缩,位置为(i, j)的格子对应的编号为 i * n + j
vector<vector<int>> st(n,vector<int>(m,0));
st[0][0] = 1;
while(q.size()){
int xx = q.front().first;
int yy =q.front().second;
if(xx == n-1 && yy == m-1) return true;
// cout<<xx<<" "<<yy<<endl;
q.pop();
for(int i=0;i<4;i++){
int nx = xx + dx[i];
int ny = yy + dy[i];
if(nx < 0 || nx >= n || ny < 0 || ny >= m || st[nx][ny]) continue;
if(abs(g[xx][yy] - g[nx][ny]) > x) continue;
st[nx][ny] = 1;
q.push({nx,ny});
}
}
return false;
}
};
2)并查集
将n*m 个节点放入并查集中,将图中的所有边按照权值从小到大进行排序,并依次加入并查集中,当某次加入一条边时,这两个点联通了,此时的x就是答案。(有点类似最小生成树?)
(把vector放在方法()里TLE了好多次。。)
struct edge{
int u,v,w;
bool operator<(const edge &t)const{
return w < t.w;
}
};
class Solution {
public:
vector<int> f;
int minimumEffortPath(vector<vector<int>>& g) {
int n = g.size();
int m = g[0].size();
vector<edge> e;
vector<int> ff(n*m);
for(int i=0;i<n*m;i++) ff[i] = i;
f = ff;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int id = i * m + j;
if(i) e.push_back({id-m,id,abs(g[i][j] - g[i-1][j])});
if(j) e.push_back({id-1,id,abs(g[i][j] - g[i][j-1])});
}
}
sort(e.begin(),e.end());
int res = 0;
for(int i=0;i<e.size();i++){
int u = e[i].u,v = e[i].v,w= e[i].w;
u = finds(u);
v = finds(v);
// cout<<u<<" "<<v<<endl;
if(u != v){
f[v] = u;
}
if(finds(0) == finds(n*m-1)){
res = w;
break;
}
}
return res;
}
int finds(int x){
return x == f[x] ? x : f[x] = finds(f[x]);
}
};
3)最短路变形
定义最短路径为所经过的所有边权的最大值,而不是求和。
用堆优化dijkstra
求最短路
https://en.wikipedia.org/wiki/A*_search_algorithm
https://en.wikipedia.org/wiki/Consistent_heuristic
https://en.wikipedia.org/wiki/Admissible_heuristic
参考学习 Dijkstra 算法的本质
struct node{
int x,y,w;
bool operator<(const node &t)const{
return w > t.w;
}
};
class Solution {
public:
const int inf = 1e8;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int minimumEffortPath(vector<vector<int>>& g) {
int n = g.size();
int m = g[0].size();
priority_queue<node> q;
q.push({0,0,0});
int ed = n * m - 1;
vector<int> dis(n*m,inf),st(n*m,0);
dis[0] = 0;
while(q.size()){
auto t = q.top();
int x = t.x,y = t.y,w = t.w;
q.pop();
int id = x * m + y;
if(st[id]) continue;
st[id] = 1;
if(x == n-1 && y == m-1){
break;
}
for(int i=0;i<4;i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if(max(w,abs(g[x][y] - g[nx][ny])) >= dis[ed]) continue;
dis[nx * m + ny] = max(w,abs(g[x][y] - g[nx][ny]));
q.push({nx,ny,dis[nx * m + ny]});
}
}
return dis[ed];
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】