※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 4386번 문제인 별자리 만들기이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/4386
4386번: 별자리 만들기
도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다. 별자리를 이루는 선은 서로 다른 두 별을 일
www.acmicpc.net
주어진 별 N개에 대하여 서로 다른 별 사이에 두 별 사이 거리를 가중치로 하는 에지를 갖는 완전그래프를 생각해보자.
이 때, 문제에서 구하는 별자리의 가중치는 이 완전그래프의 MST(minimum spanning tree; 최소 신장 트리)의 가중치와 같게 된다. 이를 구현하여 문제를 해결하자. 글쓴이는 Kruskal 알고리즘을 이용하여 문제를 해결했다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
struct point {
double x, y;
point() {
this->x = this->y = 0;
}
point(double x, double y) {
this->x = x, this->y = y;
}
};
struct edge {
int x, y;
double dist;
edge(int x, int y, double dist) {
this->x = x, this->y = y, this->dist = dist;
}
};
bool comp(edge e1, edge e2) {
return e1.dist < e2.dist;
}
point points[100];
vector<edge> edges;
int uf[100];
int findf(int x) {
if (x == uf[x]) return x;
return uf[x] = findf(uf[x]);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout << fixed;
cout.precision(10);
int N; cin >> N;
for (int i = 0; i < N; i++) {
double x, y; cin >> x >> y;
points[i] = point(x, y);
for (int j = 0; j < i; j++) {
double dist = sqrt((points[i].x - points[j].x) * (points[i].x - points[j].x) + (points[i].y - points[j].y) * (points[i].y - points[j].y));
edges.emplace_back(edge(j, i, dist));
}
}
sort(edges.begin(), edges.end(), comp);
for (int i = 0; i < N; i++) uf[i] = i;
double ans = 0;
for (auto e : edges) {
int x = e.x, y = e.y;
int fx = findf(x), fy = findf(y);
if (fx == fy) continue;
ans += e.dist;
uf[fy] = fx;
}
cout << ans;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 4779 // C++] 칸토어 집합 (0) | 2021.11.27 |
---|---|
[BOJ 17829 // C++] 222-풀링 (0) | 2021.11.26 |
[BOJ 2448 // C++] 별 찍기 - 11 (0) | 2021.11.24 |
[BOJ 5639 // C++] 이진 검색 트리 (0) | 2021.11.23 |
[BOJ 15353 // C++] 큰 수 A+B (2) (0) | 2021.11.22 |