티스토리 뷰
문제
2887번: 행성 터널
첫째 줄에 행성의 개수 N이 주어진다. (1 ≤ N ≤ 100,000) 다음 N개 줄에는 각 행성의 x, y, z좌표가 주어진다. 좌표는 -109보다 크거나 같고, 109보다 작거나 같은 정수이다. 한 위치에 행성이 두 개 이��
www.acmicpc.net
문제 풀이
1. 두 점을 연결하는 비용은 각 x, y, z좌표끼리 차의 최소 값이므로 N개의 행성을 연결하려면 좌표끼리의 차를 값으로 가지는 N - 1개의 간선을 찾아야 합니다.
2. 이는 아래의 관찰을 통해 각 축에 대해서 좌표를 정렬했을 때 인접한 점들의 차만 간선에 추가하는 방법을 통해 해결했습니다.
-
서로 인접한 세 점 A, B, C에 대해 모든 점을 연결할 때, ①은 A, C, B 순으로 ②은 A, B, C순으로 연결할 때의 총길이라고 한다. (① |AC| + |BC|, ② |AB| + |BC|)
-
간선에 추가하는 좌표끼리의 차는 최소 값을 가져야 하고, |AC| > |AB|이므로 서로 인접한 점들의 좌표 차를 간선에 추가한다.
3. 이렇게 구한 간선들 중 혹시나 임의의 점 A, B에 대해서 x좌표의 차, y좌표의 차, z좌표의 차 중에서 같은 값이 존재해 두 점을 잇는 간선이 중복해서 추가되지 않을까 생각할 수 있으나 이는 merge할 때 다른 점들에 대해서만 연결하게 하므로 일어나지 않습니다.
코드
#include <bits/stdc++.h>
using namespace std;
struct P {
int x, y, z, idx;
P(int x1, int y1, int z1, int i1) : x(x1), y(y1), z(z1), idx(i1) {}
};
struct edge {
int u, v, w;
edge(int u1, int v1, int w1) : u(u1), v(v1), w(w1) {}
bool operator <(edge& o) {
return w < o.w;
}
};
int n, a, b, c, ans, cnt;
vector<P> v;
vector<int> p;
vector<edge> e;
int find(int x) {
if (p[x] < 0) return x;
return p[x] = find(p[x]);
}
bool merge(int u, int v) {
u = find(u), v = find(v);
if (u == v) return 0;
p[v] = u;
return 1;
}
bool cmp1(P i, P j) { return i.x < j.x; }
bool cmp2(P i, P j) { return i.y < j.y; }
bool cmp3(P i, P j) { return i.z < j.z; }
int main() {
cin.tie(NULL); cout.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> n;
p.resize(n, -1);
for (int i = 0; i < n; i++) {
cin >> a >> b >> c;
v.push_back({ a,b,c,i });
}
sort(v.begin(), v.end(), cmp1);
for (int i = 1; i < n; i++) e.push_back(edge(v[i].idx, v[i - 1].idx, abs(v[i].x - v[i - 1].x)));
sort(v.begin(), v.end(), cmp2);
for (int i = 1; i < n; i++) e.push_back(edge(v[i].idx, v[i - 1].idx, abs(v[i].y - v[i - 1].y)));
sort(v.begin(), v.end(), cmp3);
for (int i = 1; i < n; i++) e.push_back(edge(v[i].idx, v[i - 1].idx, abs(v[i].z - v[i - 1].z)));
sort(e.begin(), e.end());
for (int i = 0;; i++) {
if (merge(e[i].u, e[i].v)) {
ans += e[i].w;
cnt++;
if (cnt == n - 1) break;
}
}
cout << ans;
}
'Algorithm > BOJ' 카테고리의 다른 글
[백준 14719] 빗물 (0) | 2020.11.01 |
---|---|
[백준 20055] 컨베이어 벨트 위의 로봇 (0) | 2020.10.27 |
[백준 12107] 약수 지우기 게임 1 (0) | 2020.10.05 |
[백준 15927] 회문은 회문아니야!! (0) | 2020.10.05 |
[백준 2381] 최대거리 (0) | 2020.10.05 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 파싱
- 2022 카카오블라인드
- 2022 KAKAO BLIND RECRUITMENT
- 누적합
- 카카오 2차코딩테스트
- 2022 카카오 블라인드 코딩테스트
- 프로그래머스 월간코드챌린지
- 카카오 2021
- 2020 KAKAO BLIND RECRUITMENT
- 프로그래머스
- 2021 KAKAO BLIND
- DP
- 카카오 2020 인턴십
- 시뮬레이션
- 카카오 인턴십
- 구현
- Kakaoblind
- 프로그래머스 위클리 9주차
- 유니온파인드
- 동적계획법
- BFS
- 표 편집
- 투포인터
- 트리
- 2021 카카오 블라인드
- 카카오 표 편집
- 이분탐색
- 위클리 챌린지
- 게임이론
- 백준
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함