题目链接
二维坐标系上有起点(sx,sy)
,终点(tx,ty)
任意两点间的距离是曼哈顿距离(无向边)
另外给出特殊路径(有向边) u,v,w
表示u->v
的距离为w
建图只需要建起点终点和特殊路径的点和边 因为走其他的点一定不是最优的 从a
点走到b
点再从b
点走到c
点 所走的曼哈顿距离是跟从a
点直接走到c
点一样的
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]}]];
}
};