https://leetcode-cn.com/problems/minimum-cost-to-make-at-least-one-valid-path-in-a-grid/
这道题一开始想枚举,用dfs加上各种剪枝,还是超时。后来看了题解才知道,这道题是一道最短路,关键是转变一下,改变一个方向,可以看成是cost为1的边,不改的话的cost是0,求cost最小。
用dijkstra,包括点是否已经求出最短路的标记,每个点的当前最少cost。贪心是因为边都是正的,最开始接触到的点中最少花费的点,肯定是最近的,因为后面再访问到这个点,花费肯定大于等于现在的花费。
struct Node{
int x;
int y;
int cost;
};
bool operator<(const Node &a,const Node &b){
return a.cost>b.cost;
}
class Solution {
public:
int n,m;
int is_selected[105][105];
int g_min_cost[105][105];
int ans;
vector<vector<int>> grid;
int delta[5][2]={
{0,0},
{0,1},
{0,-1},
{1,0},
{-1,0}
};
bool is_legal_pos(int x,int y){
return x>=0 && x<n && y>=0 && y<m;
}
void dijkstra(){
priority_queue<Node> q;
Node node;
node.x=node.y=0;
node.cost=0;
q.push(node);
while(!q.empty()){
while(!q.empty()){
node=q.top();
q.pop();
if(is_selected[node.x][node.y]==0){
break;
}
}
is_selected[node.x][node.y]=1;
g_min_cost[node.x][node.y]=node.cost;
if(node.x==n-1 && node.y==m-1){
ans=node.cost;
return;
}
for(int direct=1;direct<=4;direct++){
int newx=node.x+delta[direct][0];
int newy=node.y+delta[direct][1];
if(is_legal_pos(newx,newy)){
int cost=node.cost;
if(direct!=grid[node.x][node.y])
cost++;
if(cost<g_min_cost[newx][newy]){
Node temp;
temp.x=newx;
temp.y=newy;
temp.cost=cost;
q.push(temp);
}
}
}
}
}
int minCost(vector<vector<int>>& grid_) {
grid=grid_;
n=grid.size();
m=grid[0].size();
ans=INT_MAX;
memset(is_selected,0,sizeof(is_selected));
memset(g_min_cost,0x3f,sizeof(g_min_cost));
dijkstra();
return ans;
}
};