bzoj4152
The Captain
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
Input
第一行包含一个正整数n(2<=n<=200000),表示点数。
接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标。
Output
一个整数,即最小费用。
Sample Input
5
2 2
1 1
4 5
7 1
6 7
Sample Output
2
sol:分别按x,y排序,顺序建边以后跑Dijkstra即可,注意卡spfa
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const int N=200005,M=800005; int n; struct Node { ll x,y; int id; }a[N]; inline bool cmpx(Node p,Node q) {return p.x<q.x;} inline bool cmpy(Node p,Node q) {return p.y<q.y;} int tot=0,Next[M],to[M],head[N],val[M]; inline void Link(Node p,Node q) { int x=p.id,y=q.id,z=min(abs(p.x-q.x),abs(p.y-q.y)); Next[++tot]=head[p.id]; to[tot]=y; val[tot]=z; head[x]=tot; } bool Vis[N]; ll Dis[N]; struct PP { ll x,w; inline bool operator<(const PP tmp)const { return w>tmp.w; } }; priority_queue<PP>Que; inline void Dijkstra() { memset(Vis,0,sizeof Vis); memset(Dis,63,sizeof Dis); Dis[1]=0; int i; Que.push((PP){1,0}); while(!Que.empty()) { PP tmp=Que.top(); Que.pop(); if(Vis[tmp.x]) continue; Vis[tmp.x]=1; for(i=head[tmp.x];i;i=Next[i]) { if((!Vis[to[i]])&&(Dis[to[i]]>tmp.w+val[i])) { Dis[to[i]]=tmp.w+val[i]; Que.push((PP){to[i],Dis[to[i]]}); } } } } int main() { int i; R(n); for(i=1;i<=n;a[i].id=i,i++) {R(a[i].x); R(a[i].y);} sort(a+1,a+n+1,cmpx); for(i=1;i<n;i++) {Link(a[i],a[i+1]); Link(a[i+1],a[i]);} sort(a+1,a+n+1,cmpy); for(i=1;i<n;i++) {Link(a[i],a[i+1]); Link(a[i+1],a[i]);} // puts("2333"); Dijkstra(); Wl(Dis[n]); return 0; } /* Sample Input 5 2 2 1 1 4 5 7 1 6 7 Sample Output 2 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!