当前位置: 首页 > article >正文

力扣2662. 前往目标的最小代价

力扣2662. 前往目标的最小代价

题目

在这里插入图片描述

题目解析及思路

题目要求返回从start到target的最小代价,其中有若干条特殊路径

最短路径一定是从st->特殊点->…->特殊点->target

用特殊点建图然后bfs

代码

class Solution {
public:
    int minimumCost(vector<int>& start, vector<int>& target, vector<vector<int>>& specialRoads) {
        typedef pair<int, int> PII;
        map<PII,int> mp;
        //将(x,y)入图
        auto add = [&](int x,int y){
            PII p = PII(x,y);
            if(mp.count(p)) return;
            int idx = mp.size();
            mp[p] = idx;
        };

        //将start和target入图
        add(start[0],start[1]);
        add(target[0],target[1]);

        //将特殊路径入图
        for(auto road:specialRoads){
            add(road[0],road[1]);
            add(road[2],road[3]);
        }

        int n = mp.size();
        //将每个特殊点的坐标存下来
        int X[n],Y[n];
        for(auto it = mp.begin();it != mp.end();it ++){
            X[it->second] = it->first.first;
            Y[it->second] = it->first.second;
        }

        //建图
        vector<int> e[n];
        vector<long long> v[n];

        //任意两点可以互相到达
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i != j){
                    e[i].push_back(j);
                    v[i].push_back(abs(X[i] - X[j]) + abs(Y[i] - Y[j]));
                }
            }
        }

        //n条特殊路径,额外加上
        for(auto road : specialRoads){
            int sn = mp[PII(road[0],road[1])];
            int fn = mp[PII(road[2],road[3])];
            e[sn].push_back(fn);
            v[sn].push_back(road[4]);
        }

        //从S到T
        int S = mp[PII(start[0],start[1])] ,T = mp[PII(target[0],target[1])];
        long long dis[n];
        memset(dis,-1,sizeof(dis));
        typedef pair<long long,int> PLI;
        //默认是个大顶堆,存路径的时候得加个负号,可以改成小顶堆就不用加了
        priority_queue<PLI> pq;
        //first存路径长度,second存当前点的编号
        pq.push(PLI(0,S));

        while(pq.size()){
            PLI p = pq.top();
            pq.pop();
            int sn = p.second;
            long long d = -p.first;
            //防止重复遍历
            //如果dis>=0,说明已经被更新过,是最短的,不需要再更新了
            if(dis[sn] >= 0) continue;
            //取出说明sn的dis值是最短的了
            dis[sn] = d;
            //枚举连接的其他点
            for(int i=0;i<e[sn].size();i++){
                int fn = e[sn][i];
                if(dis[fn] >= 0) continue;
                //因为是大顶堆,所以边权都加个负号
                pq.push(PLI(-d-v[sn][i],fn));
            }
        }
        return dis[T];
    }
};

http://www.kler.cn/a/568413.html

相关文章:

  • DeepSeek掘金——DeepSeek R1驱动的PDF机器人
  • 隐式转换为什么导致索引失效
  • LeetCode热题100刷题17
  • 15. C++多线程编程-网络编程-GUI编程(如Qt)学习建议
  • 16.4 LangChain LCEL 接口全解析:同步、异步与批处理的正确打开方式
  • Java 容器梳理
  • 分布式拒绝服务(DDoS)攻击检测系统的设计与实现
  • 基金 word-->pdf图片模糊的解决方法
  • MATLAB代码:机器学习-分类器
  • RAG项目实战:金融问答系统
  • 物联网同RFID功能形态 使用场景的替代品
  • Android 图片压缩详解
  • python中单例模式应用
  • 【计算机网络入门】初学计算机网络(九)
  • 2025年2月最新一区SCI-海市蜃楼搜索优化算法Mirage search optimization-附Matlab免费代码
  • 蓝桥杯 灯笼大乱斗【算法赛】
  • android智能指针android::sp使用介绍
  • Pytorch为什么 nn.CrossEntropyLoss = LogSoftmax + nn.NLLLoss?
  • 使用Docker快速搭建Redis主从复制
  • 【硬件工程师成长】之是否需要组合电容进行滤波的考虑