D - Returning Home
参考:D:Returning Home-Codeforces Round #675 (Div. 2)
最短路的题难点在于建图,这道题的图不是特别难建
思路:对于每一个点,分别与 x 轴和 y 轴上相邻的两个点,连边,然后起点与每一个点连边即可。
//Created by CAD
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define pii pair<int,int>
#define fi first
#define se second
#define mst(name, value) memset(name,value,sizeof(name))
using namespace std;
const int maxn=1e5+5;
pii a[maxn];
int d[maxn];
bool vis[maxn];
vector<pii> g[maxn];
struct node{
int x,y,id;
}p[maxn];
bool cmp1(const node &a,const node &b){
return a.x<b.x;
}
bool cmp2(const node &a,const node &b){
return a.y<b.y;
}
void dij(int s){
priority_queue<pii,vector<pii>,greater<pii>> q;
mst(d,0x3f);
d[s]=0;
q.push({0,s});
while(!q.empty()){
pii now=q.top();
q.pop();
vis[now.se]=1;
for(pii &i:g[now.se]){
if(vis[i.fi]) continue;
if(d[i.fi]>now.fi+i.se)
d[i.fi]=now.fi+i.se,q.push({d[i.fi],i.fi});
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n,m; cin>>n>>m;
int sx,sy,fx,fy;cin>>sx>>sy>>fx>>fy;
for(int i=1;i<=m;++i){
cin>>a[i].fi>>a[i].se;
p[i]={a[i].fi,a[i].se,i};
int w=min(abs(sx-a[i].fi),abs(sy-a[i].se));
g[0].push_back({i,w});
g[i].push_back({0,w});
}
sort(p+1,p+1+m,cmp1);
for(int i=1;i<m;++i){
node &c=p[i],&d=p[i+1];
int w=min(abs(d.x-c.x),abs(d.y-c.y));
g[c.id].push_back({d.id,w});
g[d.id].push_back({c.id,w});
}
sort(p+1,p+1+m,cmp2);
for(int i=1;i<m;++i){
node &c=p[i],&d=p[i+1];
int w=min(abs(d.x-c.x),abs(d.y-c.y));
g[c.id].push_back({d.id,w});
g[d.id].push_back({c.id,w});
}
dij(0);
int ans=abs(sx-fx)+abs(sy-fy);
for(int i=1;i<=m;++i)
ans=min(ans,d[i]+abs(a[i].fi-fx)+abs(a[i].se-fy));
cout<<ans<<endl;
return 0;
}