The Captain
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
Input
第一行包含一个正整数n(2<=n<=200000),表示点数。
接下来n行,每行包含两个整数x[i],yi,依次表示每个点的坐标。
Output
一个整数,即最小费用。
Sample Input
5
2 2
1 1
4 5
7 1
6 7
Sample Output
2
求出欧式距离,对于xy分别跑dijstra,如果SPFA要加堆优化。
/**
* bzoj 4152 - B
* Accepted
* Author:lemonoil
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cctype>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <set>
#include <stack>
#include <vector>
#include <map>
#include <queue>
#include <list>
using namespace std;
const int N = 200005;
const int inf = 2100000000;
int n,k;
int xx[N],yy[N],d[N],tot,head[N];
struct edge{
int to,w,next;
}e[N<<2];
struct data{
int x,y;
void read(){
scanf("%d%d",&x,&y);
}
}a[N<<2];
int cmpx(const int i,const int j){
return a[i].x<a[j].x;
}
int cmpy(const int i,const int j){
return a[i].y<a[j].y;
}
void addege(int x,int y,int z){
e[++tot].next=head[x];e[tot].to=y;e[tot].w=z;head[x]=tot;
}
void add(int x,int y,int z){
addege(x,y,z);addege(y,x,z);
}
struct node{
int x,d;
bool operator < (const node & rhs)const{
return d>rhs.d;
}
node(){}
node(int x,int d):x(x),d(d){}
};
priority_queue<node> Q;
void dijk(){
for(int i=0;i<=n;i++)d[i]=inf;
Q.push(node(0,0));d[0]=0;
while(!Q.empty()){
node t=Q.top();Q.pop();
if(d[t.x]!=t.d)continue;
for(int i=head[t.x];i;i=e[i].next){
if(d[e[i].to]>d[t.x]+e[i].w){
d[e[i].to]=d[t.x]+e[i].w;
Q.push(node(e[i].to,d[e[i].to]));
}
}
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
a[i].read();
xx[i]=yy[i]=i;
}
sort(xx,xx+n,cmpx);
for(int i=0;i<n-1;i++){
data *x=a+xx[i],*y=a+xx[i+1];
if((y->x-x->x)<=abs(x->y-y->y)){
add(xx[i],xx[i+1],(y->x - x->x));
}
}
sort(yy,yy+n,cmpy);
for(int i=0;i<n-1;i++){
data *x=a+yy[i],*y=a+yy[i+1];
if((y->y-x->y)<=abs(x->x-y->x)){
add(yy[i],yy[i+1],y->y - x->y);
}
}
dijk();
printf("%d\n",d[n-1]);
return 0;
}