题解 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;
}

posted @ 2020-11-29 12:48  Blancа  阅读(118)  评论(6编辑  收藏  举报
哈哈,你打开了控制台,是想要看看我的秘密吗?
莫挨老子!