zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    导入已有项目到svn
    Linux用ICMP协议实现简单Ping网络监测功能
    c++ tcp 服务器和客户端例子
    C++ Socket 编程
    c++工厂模式和多线程结合
    Linux中ls命令详解
    Mac OS X 11中的/usr/bin 的“Operation not permitted”
    Warning: mysql_connect(): No such file or directory 解决方案总结(操作系统: Mac)
    页面组件渲染小组件(重点)
    Vue 路由
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4658577.html
Copyright © 2011-2022 走看看