• AT2643 [ARC076B] Built?


    原题链接

    • 题意:给出 (n <= 1e5) 个网格图点位置,然后让求所有点连起来的最小花费,即特殊的最小生成树,两个点之间相连的花费是 (min(|x_a - x_b|, |y_a - y_b|))
    • 题解:好像和之前做过一道dij的cf题类似。首先 (n^2) 建边不可取,那就是先按横坐标排序,然后相邻之间 (|x_i - x_j|)必然是最优的,加入预选,然后再按照 (y) 坐标,然后也是相邻的 (|y_i - y_j|) 是最优的,然后最后就是 (kruskal)
    • 代码:
    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll inf = 0x3f3f3f3f;
    const ll N = 1e5 + 9;
    struct edge {
        int x, y, w;
    }e[N << 2], a[N << 2];
    struct node {
        int x, y, id;
    }p[N];
    bool cmp1(node a, node b) {return a.x < b.x;}
    bool cmp2(node a, node b) {return a.y < b.y;}
    bool cmp3(edge a, edge b) {return a.w < b.w;}
    int f[N << 2];
    int Find(int x){return f[x] == x?x:f[x] = Find(f[x]);}
    signed main() {
        int n;scanf("%d", &n);
        for (int i = 1; i <= n; i ++) {
            scanf("%d%d", &p[i].x, &p[i].y);
            p[i].id = i;
        }
        for (int i = 0; i <= n + 2; i ++) f[i] = i;
        sort(p + 1, p + 1 + n, cmp1);
        int nn = 0;
        for (int i = 1; i < n; i ++) e[++nn] = {p[i].id, p[i + 1].id, abs(p[i].x - p[i + 1].x)};
        sort(p + 1, p + 1 + n, cmp2);
        for (int i = 1; i < n; i++) e[++nn] = {p[i].id, p[i + 1].id, abs(p[i].y - p[i + 1].y)};
        sort(e + 1, e + 1 + nn, cmp3);
        int ans =0 ;
        for (int i = 1; i <= nn; i ++) {
            int fx = Find(e[i].x);
            int fy = Find(e[i].y);
            if (fx == fy)continue;
            f[fx] = fy;
            ans += e[i].w;
        }
        printf("%d
    ", ans);
    }
    
  • 相关阅读:
    sort排序
    js数组
    json数据格式 与 for in
    js 定时器
    鼠标滚轮事件
    cookie
    POJ 2387 Til the Cows Come Home
    POJ 1459 Power Network
    HDU 5389 Zero Escape
    HDU 5387 Clock
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14688979.html
Copyright © 2020-2023  润新知