dijktra算法两例

力扣743:网络延迟时间
力扣1631:最小体力消耗路径

第一道:完全的模版题

class Cmp{
    public:
    bool operator()(const vector<int>& a, const vector<int>& b){
        return a[1] > b[1];
    }
};
class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int n, int k) {
        vector<int>distance(n+1, INT_MAX); // 到源点的距离
        vector<bool>visited(n+1, false);
        int cnt = 0;
        vector<vector<vector<int>>>graph(n+1, vector<vector<int>>());
        distance[k] = 0;
        for(auto time : times){
            int u = time[0], v = time[1], w = time[2];
            graph[u].push_back({v, w});
        }
        priority_queue<vector<int>, vector<vector<int>>, Cmp>pq; // 小根堆
        // for(auto egde : graph[k]){
        //     pq.push({egde[0], egde[1]});
        // }
        pq.push({k, 0}); // 到原点距离进堆
        while(!pq.empty()){
            vector<int>top = pq.top();
            int v = top[0]; //w = top[1];
            pq.pop();
            if(!visited[v]){
                //尝试用该记录优化后面路径
                visited[v] = true;
                for(auto egde : graph[v]){
                    int nex = egde[0];
                    if(!visited[nex] && distance[v] + egde[1] < distance[nex]){
                        distance[nex] = distance[v] + egde[1];
                        pq.push({nex, distance[nex]});
                    }
                }
            }
        }
        int res = -1;
        for(int i=1;i<=n;i++){
            if(distance[i]==INT_MAX) return -1;
            res = max(res, distance[i]);
        }
        return res;
    }
};

第二题:看成从源点到右下角点的特殊路径,最短路径更新规则由

int nc = max(cost, abs(heights[row][col] - heights[nx][ny]));

的规则给出

完整代码如下:

class Cmp{
public:
bool operator()(const vector<int>& a, const vector<int>& b){
    return a[2] > b[2];
}
};
const int mov[4][2] = {
    {1,0},{0,1},{-1,0},{0,-1}
};
class Solution {
public:
    int minimumEffortPath(vector<vector<int>>& heights) {
        int n = heights.size();
        int m = heights[0].size();
        vector<vector<int>>distance(n, vector<int>(m, INT_MAX));
        vector<vector<bool>>visited(n, vector<bool>(m, false));
        //小根堆内每个vector元素:
        // [0] : 行号
        // [1] : 列号
        // [2] : 到源点的“距离”(花费)

        priority_queue<vector<int>, vector<vector<int>>, Cmp>pq;
        pq.push({0,0,0});
        distance[0][0] = 0; // 可以不用,后面不会优化(0,0)点
        
        while(!pq.empty()){
            vector<int> record = pq.top(); pq.pop();
            //堆顶元素被拿出来,表示其到源点的距离已经得到最好优化
            //用堆顶元素优化下一位置的 花费, 堆顶元素优化一轮后,就visited设为true
            //表示 其利用价值耗尽
            int row = record[0], col = record[1], cost = record[2];
            if(visited[row][col]) continue;
            visited[row][col] = true;
            //剪枝,更新到目标点
            if(row == n-1 && col == m-1){
                return cost;
            }
            //利用堆顶元素去优化后续元素
            for(int i=0;i<4;i++){
                int nx = row + mov[i][0];
                int ny = col + mov[i][1];
                if(nx>=0 && nx <n && ny>=0 && ny <m && !visited[nx][ny]){
                    //尝试更新到源点距离
                    int nc = max(cost, abs(heights[row][col] - heights[nx][ny]));
                    if(nc < distance[nx][ny]){
                        pq.push({nx, ny, nc});
                        distance[nx][ny] = nc;
                        //visited[nx][ny] = true; \\!不能用这一行
                    }

                }
            }
        }
        return -1;
    }
};
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雾影林深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值