zoukankan      html  css  js  c++  java
  • 题解 AT2643 【[ARC076B] Built?】

    传送门

    思路

    暴力的话就(n^2)建边,然后跑一遍最小生成树
    思考怎么优化,有一个很显然的性质,答案一定是在横坐标相邻的点之间或者纵坐标相邻的点之间连边,没有比这种方法更优的连边方法,也就是如果(x_a) (<) (x_b) (<) (x_c),那么对于横坐标而言这个b点不可能作出贡献,纵坐标同理,所以我们将点分别按横纵坐标排序,预处理出来每条边,然后跑一次kruskal最小生成树就好了

    代码实现

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn = 1e5 + 50;
    inline int read () {
    	int x = 0, f = 1; char ch = getchar();
    	for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    	return x * f;
    }
    int n, fa[maxn], tot;
    struct Node { int id, x, y; } node[maxn];
    inline bool cmp1 (Node A, Node B) { return A.x < B.x; }
    inline bool cmp2 (Node A, Node B) { return A.y < B.y; }
    inline int find_root (int a) { return fa[a] == a ? a : fa[a] = find_root(fa[a]); }
    inline void merge (int a, int b) { fa[find_root(a)] = find_root(b); }
    struct Edge { int from, to, val; } edge[maxn << 1];
    inline bool cmp3 (Edge A, Edge B) { return A.val < B.val; }
    int main () {
    	n = read();
    	for (register int i = 1; i <= n; i++) fa[i] = i;
    	for (register int i = 1; i <= n; i++) node[i].id = i, node[i].x = read(), node[i].y = read();
    	sort (node + 1, node + 1 + n, cmp1);
    	for (register int i = 1; i < n; i++) {
    		edge[++tot].from = node[i].id, edge[tot].to = node[i + 1].id;
    		edge[tot].val = min (abs(node[i].x - node[i + 1].x), abs (node[i].y - node[i + 1].y));
    	}
    	sort (node + 1, node + 1 + n, cmp2);
    	for (register int i = 1; i < n; i++) {
    		edge[++tot].from = node[i].id, edge[tot].to = node[i + 1].id;
    		edge[tot].val = min (abs(node[i].x - node[i + 1].x), abs (node[i].y - node[i + 1].y));
    	}
    	sort (edge + 1, edge + 1 + tot, cmp3);
    	int mtot = 0;
    	long long ans = 0;
    	for (register int i = 1; i <= tot; i++) {
    		if (mtot == n - 1) break;
    		int x = edge[i].from, y = edge[i].to;
    		if (find_root(x) == find_root(y)) continue;
    		mtot++;
    		merge (x, y);
    		ans += edge[i].val;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    分布式训练基本原理
    服务化部署框架Paddle Serving
    Paddle Inference原生推理库
    源码编译优化
    推理部署概述
    深度学习模型组网
    在这里
    什么是响应式编程,为什么使用它?
    时间管理:如何充分利用你的24小时-吉姆·兰德尔.pdf
    Win10激活工具
  • 原文地址:https://www.cnblogs.com/hzoi-liujiahui/p/14055988.html
Copyright © 2011-2022 走看看