BZOJ 4152: [AMPPZ2014]The Captain( 最短路 )

先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作...然后就dijkstra 

------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
  
#define rep(i, n) for(int i = 0; i < n; i++)
#define clr(x, c) memset(x, c, sizeof(x))
  
using namespace std;
 
const int inf = 1000000009, maxn = 200009;
 
struct edge {
int to, w;
edge*next;
} E[maxn << 2], *pt = E, *head[maxn];
 
struct node {
int x, d;
bool operator < (const node&o) const {
return d > o.d;
}
};
 
struct P {
int x, y;
inline void Read() {
scanf("%d%d", &x, &y);
}
} A[maxn];
 
inline void add(int u, int v, int w) {
pt->to = v, pt->w = w;
pt->next = head[u];
head[u] = pt++;
}
#define add_edge(u, v, w) add(u, v, w), add(v, u, w)
 
bool cmpX(const int i, const int j) {
return A[i].x < A[j].x;
}
 
bool cmpY(const int i, const int j) {
return A[i].y < A[j].y;
}
 
int d[maxn], n, X[maxn], Y[maxn];
priority_queue<node> Q;
 
void dijkstra() {
rep(i, n) d[i] = inf;
d[0] = 0, Q.push( (node) {0, 0} );
while(!Q.empty()) {
node t = Q.top(); Q.pop();
if(d[t.x] != t.d) continue;
for(edge*e = head[t.x]; e; e = e->next) if(d[e->to] > d[t.x] + e->w) {
d[e->to] = d[t.x] + e->w;
Q.push( (node) {e->to, d[e->to]} );
}
}
}
 
int main() {
freopen("test.in", "r", stdin);
cin >> n;
rep(i, n) {
   A[i].Read();
   X[i] = Y[i] = i;
}
sort(X, X + n, cmpX);
rep(i, n - 1) {
P*a = A + X[i], *b = A + X[i + 1];
if(b->x - a->x <= abs(a->y - b->y)) add_edge(X[i], X[i + 1], b->x - a->x);
}
sort(Y, Y + n, cmpY);
rep(i, n - 1) {
P*a = A + Y[i], *b = A + Y[i + 1];
if(b->y - a->y <= abs(a->x - b->x)) add_edge(Y[i], Y[i + 1], b->y - a->y);
}
dijkstra();
printf("%d ", d[n - 1]);
return 0;
}

------------------------------------------------------------------------

4152: [AMPPZ2014]The Captain

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 272  Solved: 104
[Submit][Status][Discuss]

Description

给定平面上的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

HINT

Source

原文地址:https://www.cnblogs.com/JSZX11556/p/4658577.html