1. 程式人生 > >bzoj4152 [AMPPZ2014]The Captain

bzoj4152 [AMPPZ2014]The Captain

std cap git tin edge greate solution pri include

Description

給定平面上的 \(n\) 個點,定義 \((x_1,y_1)\)\((x_2,y_2)\) 的費用為 \(\min(|x_1-x_2|,|y_1-y_2|)\) ,求從 \(1\) 號點走到 \(n\) 號點的最小費用。

Input

第一行包含一個正整數 \(n(2\le n\le 200000)\) ,表示點數。

接下來 \(n\) 行,每行包含兩個整數 \(x[i],y[i] (0\le x[i],y[i]\le 10^9)\) ,依次表示每個點的坐標。

Output

一個整數,即最小費用。

Sample

Sample Input

5
2 2
1 1
4 5
7 1
6 7

Sample Output

2

Solution

這傻逼題吧...這種題都出爛了...

寫這道題的原因是聽說這道題卡 \(\mathrm{spfa}\)

#include<bits/stdc++.h>
using namespace std;

#define N 200001
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define ll long long
#define pli pair<ll, int>

inline int read() {
    int x = 0, flag = 1; char ch = getchar(); while
(!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); } while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag; } struct point { int x, y, id; }a[N]; bool cmpx(const point& p1, const point& p2) { return p1.x < p2.x; } bool
cmpy(const point& p1, const point& p2) { return p1.y < p2.y; } int n, head[N], tot; ll dis[N]; bool vis[N]; priority_queue<pli, vector<pli>, greater<pli> > q; struct edge{ int v, next; ll w; }e[N << 2]; inline void insert(int u, int v, ll w) { e[++tot].v = v, e[tot].w = w, e[tot].next = head[u], head[u] = tot; } #define add(u, v, w) insert(u, v, w), insert(v, u, w) void dijkstra() { rep(i, 2, n) dis[i] = (1ll << 62ll); q.push(make_pair(0, 1)); while (!q.empty()) { int u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u], v; i; i = e[i].next) if (dis[v = e[i].v] > dis[u] + e[i].w) dis[v] = dis[u] + e[i].w, q.push(make_pair(dis[v], v)); } } int main() { n = read(); rep(i, 1, n) a[i].x = read(), a[i].y = read(), a[i].id = i; sort(a + 1, a + 1 + n, cmpx); rep(i, 2, n) add(a[i].id, a[i - 1].id, a[i].x - a[i - 1].x); sort(a + 1, a + 1 + n, cmpy); rep(i, 2, n) add(a[i].id, a[i - 1].id, a[i].y - a[i - 1].y); dijkstra(); printf("%lld", dis[n]); return 0; }

bzoj4152 [AMPPZ2014]The Captain