[BZOJ4152]4152: [AMPPZ2014]The Captain
[BZOJ4152]4152: [AMPPZ2014]The Captain
题意
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
题解
以X坐标排一遍序,将相邻的点连边,边权为X坐标的差
对Y再做一遍同样的操作
跑最短路即可
正确性显然
#include<bits/stdc++.h> using namespace std; const int MAXN = 200000 + 10; inline int read() { int f=1,x=0; char ch; do { ch=getchar(); if(ch=='-') f=-1; }while(ch<'0'||ch>'9'); do { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }while(ch>='0'&&ch<='9'); return f*x; } int n; struct Query { int x; int y; int id; }a[MAXN]; inline bool cmp(Query a1,Query a2) { return a1.x<a2.x; } inline bool cmp1(Query a1,Query a2) { return a1.y<a2.y; } struct node { int id; long long dis; friend bool operator < (node a1,node a2) { return a1.dis>a2.dis; } }; long long dis[MAXN]; priority_queue<node>q; struct Edge { int to; int next; int val; }g[MAXN*4]; int head[MAXN],cnt; inline void addedge(int a,int b,int c) { ++cnt;g[cnt].to=b;g[cnt].next=head[a];g[cnt].val=c;head[a]=cnt; } int main() { n=read(); for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].id=i; sort(a+1,a+n+1,cmp); for(int i=1;i<n;i++) { addedge(a[i].id,a[i+1].id,a[i+1].x-a[i].x); addedge(a[i+1].id,a[i].id,a[i+1].x-a[i].x); } sort(a+1,a+n+1,cmp1); for(int i=1;i<n;i++) { addedge(a[i].id,a[i+1].id,a[i+1].y-a[i].y); addedge(a[i+1].id,a[i].id,a[i+1].y-a[i].y); } for(int i=2;i<=n;i++) dis[i]=(1<<30); q.push(node{1,0}); while(q.size()) { node qu=q.top();q.pop(); int u=qu.id; if(qu.dis!=dis[u]) continue; for(int i=head[u];i;i=g[i].next) { int v=g[i].to; if(dis[v]>dis[u]+g[i].val) { dis[v]=dis[u]+g[i].val; q.push(node{v,dis[v]}); } } } cout<<dis[n]<<endl; return 0; }