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(|a−c|,|b−d|) 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
- 2≤N≤105
- 0≤xi,yi≤109
- All input values are integers.
Input
Input is given from Standard Input in the following format:
N x1 y1 x2 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
3 1 5 3 9 7 8
Sample Output 1
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
6 8 3 4 9 12 19 18 1 13 5 7 6
Sample Output 2
8
题目大意:给出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;
}