zoukankan      html  css  js  c++  java
  • 【BZOJ4152】The Captain

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4152


    贪心+最短路吧,如果两点之间存在一个拐点,那么经过挂点一定不会比直接到达差,这个很容易想象,因此,我们应将横纵坐标分别排序,将相邻的横纵坐标之间建边。

    细节也不多,本题的关键就是如何巧妙地建边,而不是建n^2条边。哦,据说题目卡了SPFA,和我又有啥关系呢。。。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    inline int get_num() {
        int num = 0;
        char c = getchar();
        while (c < '0' || c > '9') c = getchar();
        while (c >= '0' && c <= '9')
            num = num * 10 + c - '0', c = getchar();
        return num;
    }
    
    const int maxn = 2e5 + 5, inf = 0x3f3f3f3f;
    
    int head[maxn], eid;
    
    struct Edge {
        int v, w, next;
    } edge[4 * maxn];
    
    inline void insert(int u, int v, int w) {
        edge[++eid].v = v;
        edge[eid].w = w;
        edge[eid].next = head[u];
        head[u] = eid;
    }
    
    inline void insert2(int u, int v, int w) {
        insert(u, v, w);
        insert(v, u, w);
    }
    
    int dist[maxn], vis[maxn];
    
    struct node {
        int id, dist;
        node(int i, int d) : id(i), dist(d) {}
        bool operator < (const node& rhs) const {
            return dist > rhs.dist;
        }
    };
    
    priority_queue<node> q;
    
    inline void dijkstra() {
        memset(dist, inf, sizeof(dist));
        dist[1] = 0;
        q.push(node(1, 0));
        while (!q.empty()) {
            int u = q.top().id;
            q.pop();
            if (vis[u]) continue;
            vis[u] = 1;
            for (int p = head[u]; p; p = edge[p].next) {
                int v = edge[p].v, w = edge[p].w;
                if (dist[v] > dist[u] + w) {
                    dist[v] = dist[u] + w;
                    q.push(node(v, dist[v]));
                }
            }
        }
    }
    
    struct Point {
        int id, x, y;
    } point[maxn];
    
    bool comp1(const Point& lhs, const Point& rhs) {
        return lhs.x < rhs.x;
    }
    
    bool comp2(const Point& lhs, const Point& rhs) {
        return lhs.y < rhs.y;
    }
    
    int main() {
        int n = get_num();
        for (int i = 1; i <= n; ++i)
            point[i].id = i, point[i].x = get_num(), point[i].y = get_num();
        sort(point + 1, point + n + 1, comp1);
        for (int i = 2; i <= n; ++i)
            insert2(point[i - 1].id, point[i].id, point[i].x - point[i - 1].x);
        sort(point + 1, point + n + 1, comp2);
        for (int i = 1; i <= n; ++i)
            insert2(point[i - 1].id, point[i].id, point[i].y - point[i - 1].y);
        dijkstra();
        printf("%d", dist[n]);
        return 0;
    }
    AC代码
  • 相关阅读:
    快速排序和归并排序的迭代实现
    Longest Increasing Subsequence Review
    IOCCC 1987 最佳单行代码解读
    C++类的成员函数对应的链接器符号的解析
    Scalable Global ID Generator Design
    欧拉回路 (Euler Circuit) POJ 1780
    深入理解函数内静态局部变量初始化
    memcached 线程模型
    类的加载与ClassLoader的理解
    字符集常见码表说明
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9903031.html
Copyright © 2011-2022 走看看