AtCoder Regular Contest 076 D Built?(kruskal)

来源:互联网 发布:阿里云备案.top 编辑:程序博客网 时间:2024/06/06 22:14

点击打开题目链接

D - Built?


Time limit : 2sec / Memory limit : 256MB

Score : 500 points

Problem Statement

There are N towns on a plane. The i-th town is located at the coordinates (xi,yi). There may be more than one town at the same coordinates.

You can build a road between two towns at coordinates (a,b) and (c,d) for a cost of min(|ac|,|bd|) yen (the currency of Japan). It is not possible to build other types of roads.

Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?

Constraints

  • 2N105
  • 0xi,yi109
  • All input values are integers.

Input

Input is given from Standard Input in the following format:

Nx1 y1x2 y2:xN yN

Output

Print the minimum necessary amount of money in order to build roads so that it will be possible to travel between every pair of towns by traversing roads.


Sample Input 1

Copy
31 53 97 8

Sample Output 1

Copy
3

Build a road between Towns 1 and 2, and another between Towns 2 and 3. The total cost is 2+1=3 yen.


Sample Input 2

Copy
68 34 912 1918 113 57 6

Sample Output 2

Copy
8

Submit


题目大意:给出N个点的坐标,任意两点的权值为min(|x1-x2|,|y1-y2|),求一个最小生成树。

思路:一开始是写的两个for循环对任意两点间的比较,只能过前六个样例,后面全为RE,后来改为先对x和y分别排一遍序构图,然后kruskal一遍。

附上AC代码:

#include<iostream>#include<algorithm>using namespace std;const int maxn = 1e5 + 5;int cnt;int par[maxn];int n;struct roads {int x, y, id;roads(int _x = 0, int _y = 0, int _z = 0) :x(_x), y(_y), id(_z) {};}road[maxn], road2[maxn * 2];bool cmp1(const roads &a, const roads &b) {return a.x < b.x;}bool cmp2(const roads &a, const roads &b) {return a.y < b.y;}bool cmp3(const roads &a, const roads &b) {return a.id < b.id;}void init() {for (int i = 1; i <= n; i++)par[i] = i;}int find(int x) {if (x == par[x])return x;return par[x] = find(par[x]);}void unite(int x, int y) {x = find(x);y = find(y);if (x == y)return;par[x] = y;}bool same(int x, int y) {return find(x) == find(y);}int kruskal() {int sum = 0;init();for (int i = 0; i<cnt; i++) {roads r = road2[i];if (r.id == 0)unite(r.x, r.y);if (!same(r.x, r.y)) {unite(r.x, r.y);sum += r.id;}}return sum;}int main() {ios::sync_with_stdio(false);while (cin >> n) {for (int i = 0; i < n; i++) {cin >> road[i].x >> road[i].y;road[i].id = i + 1;}cnt = 0;sort(road, road + n, cmp1);for (int i = 1; i < n; i++) {road2[cnt++] = roads( road[i].id,road[i - 1].id,road[i].x - road[i - 1].x );}sort(road, road + n, cmp2);for (int i = 1; i < n; i++) {road2[cnt++] = roads(road[i].id, road[i - 1].id, road[i].y - road[i - 1].y);}sort(road2, road2 + cnt, cmp3);int t = kruskal();cout << t << endl;}return 0;}