题意分析
1368. 使网格图至少有一条有效路径的最小代价 - 力扣(LeetCode)
这题做法和LCP56一摸一样,放这偷懒(bushi)。就是每个点作为节点,往四周有路径,以最短路径的点更新其他路径。只是这里的路径值要自己判断方向给出。
算法思路
- 创建距离数组,三元优先队列,方向数组
- dijkstra算法,每次弹出始点到该点最短路径的点,以该点向四周发散,放入队列。
- 最后输出。本题由于是左上角到右下角,所以可以特判输出。
代码实现
typedef array<int,3> AI3;
const int inf=INT_MAX/2;
class Solution {
public:
int minCost(vector<vector<int>>& grid) {
int m=grid.size(),n=grid[0].size();
vector<vector<int>> dist(m,vector<int>(n,inf));
priority_queue<AI3,vector<AI3>,greater<>> q;
q.push({0,0,0});
vector<pair<int,int>> dirs={{0,1},{0,-1},{1,0},{-1,0}};
while(!q.empty()){
auto [cost,i,j]=q.top();q.pop();
if(dist[i][j]<inf) continue;
dist[i][j]=cost;
if(i==m-1 && j==n-1) return cost;//在这输出会快点
for(int k=0;k<4;k++){
int x=i+dirs[k].first,y=j+dirs[k].second;
if(x<0||x>=m||y<0||y>=n) continue;
if(dist[x][y]<inf) continue;
int add=(k+1==grid[i][j]?0:1);//判断方向是否相同,不同cost+1
q.push({cost+add,x,y});
}
}
return dist[m-1][n-1];
}
};
解题总结
遇到2点距离求最短距离,就可将问题抽象为点、边、路径,求最短路径通常用dijkstra,floyd,bellman-ford,逐一套用可出解。