[leetcode]2662. 前往目标的最小代价(二维坐标建图)

题目链接

题意

二维坐标系上有起点(sx,sy),终点(tx,ty)
任意两点间的距离是曼哈顿距离(无向边)
另外给出特殊路径(有向边) u,v,w表示u->v的距离为w

思路

建图只需要建起点终点和特殊路径的点和边 因为走其他的点一定不是最优的 从a点走到b点再从b点走到c点 所走的曼哈顿距离是跟从a点直接走到c点一样的

Code

using ll = long long;
#define pii pair<ll,int>
using ar2 = array<ll,2>;
void cmax(int &a,int b){a=max(a,b);};
void cmin(int &a,int b){a=min(a,b);};
const int N=1e5+10,MOD=1e9+7,INF=0x3f3f3f3f;const long long LINF=LLONG_MAX;const double eps=1e-6;

class Solution {
public:
    int getdis(int x1,int y1,int x2,int y2){
        return abs(x1-x2)+abs(y1-y2);
    }
    
    int minimumCost(vector<int>& start, vector<int>& target, vector<vector<int>>& specialRoads) {
        if(pii(start[0],start[1])==pii(target[0],target[1])) return 0;
        //二维坐标映射到一维编号
        map<pii,int>mp;//注意pii作为key必须用map,不能用unordered_map
        auto add=[&](int x,int y)->void {
            pii p=pii(x,y);
            if(mp.count(p)) return ;
            mp[p]=mp.size();
        };

        add(start[0],start[1]),add(target[0],target[1]);

        for(auto e:specialRoads){
            int x1=e[0],y1=e[1],x2=e[2],y2=e[3],w=e[4];
            add(x1,y1),add(x2,y2);
        }

        //一维编号索引到二维坐标
        int n=mp.size();//一共n个点
        unordered_map<int,int>xpos,ypos;
        for(auto [p,id]:mp){
            auto [x,y]=p;
            xpos[id]=x,ypos[id]=y;
        }

		//建图
        vector<vector<ar2>>g(n);
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                int d=getdis(xpos[i],ypos[i],xpos[j],ypos[j]);
                g[i].push_back({d,j});
                g[j].push_back({d,i});
            }
        }

        for(auto e:specialRoads){
            int x1=e[0],y1=e[1],x2=e[2],y2=e[3],w=e[4];
            int i=mp[{x1,y1}],j=mp[{x2,y2}];
            g[i].push_back({w,j});
        }

		//Dijkstra
        priority_queue<pii,vector<pii>,greater<>>pq;
        pq.emplace(0,mp[{start[0],start[1]}]);
        
        vector<ll>dis(n,LINF);
        while(pq.size()){
            auto [d,i]=pq.top();pq.pop();
            if(d>dis[i]) continue;

            for(auto [w,j]:g[i]){
                ll nd=w+d;
                if(nd<dis[j]){
                    dis[j]=nd;
                    pq.emplace(nd,j);
                }
            }
        }
        return dis[mp[{target[0],target[1]}]];
    }
};

实现细节

你可能感兴趣的:(leetcode,算法,职场和发展)