做dijkstra,但只需要贪心地把每个点连到它左边、右边、上边、下面的第一个点就可以了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=2e5+10; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 struct Node{ 22 int x,y,id; 23 }pos[maxn]; 24 int N,xnxt[maxn][2],ynxt[maxn][2]; 25 int dis[maxn],px[maxn],py[maxn]; 26 bool flag[maxn]; 27 priority_queue<pa,vector<pa>,greater<pa> > q; 28 29 inline bool cmp1(Node a,Node b){return a.x<b.x;} 30 inline bool cmp2(Node a,Node b){return a.y<b.y;} 31 32 inline void psh(int x,int d){ 33 if(dis[x]==-1||d<dis[x]){ 34 dis[x]=d; 35 if(!flag[x]) q.push(make_pair(d,x)); 36 } 37 } 38 39 inline void dijkstra(){ 40 memset(dis,-1,sizeof(dis));dis[1]=0; 41 q.push(make_pair(0,1)); 42 while(!q.empty()){ 43 int p=q.top().second;q.pop();if(flag[p]) continue; 44 flag[p]=1; 45 if(p==N) return; 46 if(xnxt[p][0]) psh(xnxt[p][0],dis[p]+px[p]-px[xnxt[p][0]]); 47 if(xnxt[p][1]) psh(xnxt[p][1],dis[p]-px[p]+px[xnxt[p][1]]); 48 if(ynxt[p][0]) psh(ynxt[p][0],dis[p]+py[p]-py[ynxt[p][0]]); 49 if(ynxt[p][1]) psh(ynxt[p][1],dis[p]-py[p]+py[ynxt[p][1]]); 50 } 51 } 52 53 int main(){ 54 //freopen(".in","r",stdin); 55 rei i,j,k; 56 N=rd(); 57 for(i=1;i<=N;i++) px[i]=pos[i].x=rd(),py[i]=pos[i].y=rd(),pos[i].id=i; 58 sort(pos+1,pos+N+1,cmp1); 59 for(i=1;i<=N;i++){ 60 xnxt[pos[i].id][0]=pos[i-1].id; 61 xnxt[pos[i].id][1]=pos[i+1].id; 62 } 63 sort(pos+1,pos+N+1,cmp2); 64 for(i=1;i<=N;i++){ 65 ynxt[pos[i].id][0]=pos[i-1].id; 66 ynxt[pos[i].id][1]=pos[i+1].id; 67 } 68 dijkstra(); 69 printf("%d\n",dis[N]); 70 return 0; 71 }