MST 알고리즘
임의의 노드 와 를 비교하여 가장 짧은 경로를 찾아 이어 가야 한다.
이 문제는 의 차이가 있을 뿐, 모든 노드끼리 이어질 가능성이 있다는 것이다. 이러한 행성간 모든 간선을 찾아 탐색하는 경우는, int
를 사용해도, 10만 10만-1 4bytes 이므로 어마어마한 메모리 초과가 발생하게 된다. 따라서 최소 스패닝 트리의 특성을 이용하여, 탐색해야 하는 값을 줄이는 것이 관건이다.
탐색 값을 줄이는 과정은 다음과 같다. (구글 참조)
int
기반의 정렬이라면 정렬 기준에 -1을 곱하는 것으로 함수를 만들지 않아도 오름차순을 하는 것이 가능하다.#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<int, pi> pii;
const int N_MAX = 1e6 + 4;
int N, p[N_MAX], cnt;
priority_queue<pii> pq;
vector<pi> arr[3];
ll result;
int findParent(int n) {
if (p[n] == n) return n;
return p[n] = findParent(p[n]);
}
bool setUnion(int n1, int n2) {
int p1 = findParent(n1);
int p2 = findParent(n2);
if (p1 == p2) return false;
p[p1] = p2;
cnt++;
return true;
}
void solve() {
while (cnt < N - 1) {
pii curr = pq.top();
pq.pop();
if (setUnion(curr.second.first, curr.second.second))
result += curr.first*-1;
}
}
void output() {
cout << result;
}
void input() {
cin >> N;
int x, y, z;
for (int i = 0; i < N; i++) p[i] = i;
for (int i = 0; i < N; i++) {
cin >> x >> y >> z;
arr[0].push_back({x, i});
arr[1].push_back({y, i});
arr[2].push_back({z, i});
};
sort(arr[0].begin(), arr[0].end());
sort(arr[1].begin(), arr[1].end());
sort(arr[2].begin(), arr[2].end());
for (int i = 0; i < N-1; i++) {
pq.push({arr[0][i].first - arr[0][i + 1].first, {arr[0][i].second, arr[0][i + 1].second}});
pq.push({arr[1][i].first - arr[1][i + 1].first, {arr[1][i].second, arr[1][i + 1].second}});
pq.push({arr[2][i].first - arr[2][i + 1].first, {arr[2][i].second, arr[2][i + 1].second}});
}
}
int main() {
input();
solve();
output();
}