题解 CF1422D 【Returning Home】
FutaRimeWoawaSete · · 题解
首先拿到这道题,切比雪夫距离?然后最短路,然后这给的
首先我们可以先想个问题:这道题是否有无用边?很明显对于一道蓝题而言优化建图的东西不可能来一个线段树优化建图之类的难码东西(更何况这是个
观察到如果我们从
于是我们根据
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int Len = 5e5 + 5;
const long long Inf = 1e18;
bool f[Len];
int n,m,s,t,cnt,head[Len];
long long dis[Len];
bool flag[Len];
struct node
{
int next,to;
long long w;
}edge[Len << 1];
struct Node
{
int x;
long long Dis;
bool operator < (const Node &Ano) const
{
return Dis > Ano.Dis;
}
}P,C;
void add(int from,int to,long long w)
{
edge[++ cnt].to = to;
edge[cnt].next = head[from];
edge[cnt].w = w;
head[from] = cnt;
}
void Dij()
{
priority_queue<Node> q;
for(int i = 1 ; i <= m ; i ++) dis[i] = Inf , f[i] = false;
dis[t] = Inf , f[t] = false;
dis[s] = 0 , f[s] = false;
P.x = s , P.Dis = 0;
q.push(P);
while(!q.empty())
{
P = q.top() ; q.pop();
if(P.x == t)
{
printf("%lld\n",P.Dis);
return;
}
if(!f[P.x])
{
f[P.x] |= 1;
for(int e = head[P.x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(dis[to] > dis[P.x] + edge[e].w)
{
dis[to] = dis[P.x] + edge[e].w;
if(!f[to])
{
C.x = to , C.Dis = dis[to];
q.push(C);
}
}
}
}
}
printf("%lld\n",dis[t]);
}
struct Point
{
int x,y,id;
}PPt[Len],S,T;
bool cmt(Point x,Point y){return x.x < y.x;}
bool cmq(Point x,Point y){return x.y < y.y;}
long long ddis(Point x,Point y){return min(abs(x.x - y.x) , abs(x.y - y.y));}
long long DDis(Point x,Point y){return abs(x.x - y.x) + abs(x.y - y.y);}
signed main()
{
scanf("%lld %lld",&n,&m);
s = m + 1 , t = m + 2;
scanf("%lld %lld %lld %lld",&S.x,&S.y,&T.x,&T.y);
S.id = m + 1 , T.id = m + 2;
for(int i = 1 ; i <= m ; i ++)
{
scanf("%lld %lld",&PPt[i].x,&PPt[i].y);
PPt[i].id = i;
add(PPt[i].id , S.id , ddis(PPt[i] , S));
add(S.id , PPt[i].id , ddis(PPt[i] , S));
add(PPt[i].id , T.id , DDis(PPt[i] , T));
add(T.id , PPt[i].id , DDis(PPt[i] , T));
}
add(S.id , T.id , DDis(S , T));
sort(PPt + 1 , PPt + 1 + m , cmt);
for(int i = 1 ; i <= m ; i ++)
{
if(i != 1)
{
add(PPt[i].id , PPt[i - 1].id , ddis(PPt[i] , PPt[i - 1]));
add(PPt[i - 1].id , PPt[i].id , ddis(PPt[i] , PPt[i - 1]));
}
}
sort(PPt + 1 , PPt + 1 + m , cmq);
for(int i = 1 ; i <= m ; i ++)
{
if(i != 1)
{
add(PPt[i].id , PPt[i - 1].id , ddis(PPt[i] , PPt[i - 1]));
add(PPt[i - 1].id , PPt[i].id , ddis(PPt[i] , PPt[i - 1]));
}
}
Dij();
return 0;
}