분류: MST, 크루스칼 알고리즘
문제
문제 설명
n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.
다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.
제한사항
- 섬의 개수 n은 1 이상 100 이하입니다.
- costs의 길이는
((n-1) * n) / 2
이하입니다. - 임의의 i에 대해, costs[i][0] 와 costs[i] [1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i] [2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다.
- 같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.
- 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.
- 연결할 수 없는 섬은 주어지지 않습니다.
입출력 예
n | costs | return |
---|---|---|
4 | [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] | 4 |
입출력 예 설명
costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다.
풀이
#include <vector>
#include <algorithm>
using namespace std;
inline int fnd(int x, vector<int> &root) {
return root[x] == -1 ? x : (root[x] = fnd(root[x], root));
}
inline void uni(int x, int y, vector<int> &root) {
root[fnd(x, root)] = fnd(y, root);
}
int solution(int n, vector<vector<int>> costs) {
vector<int> root(n, -1);
sort(costs.begin(), costs.end(),
[](const vector<int> &x, const vector<int> &y) {
return x[2] < y[2];
}
);
int ans = 0;
for(auto const &edge:costs) {
int x = edge[0], y = edge[1];
if(fnd(x, root) == fnd(y, root)) continue;
uni(x, y, root);
ans += edge[2];
}
return ans;
}
크루스칼 알고리즘을 이용한 최소신장트리(MST) 비용 계산
MST 알고리즘에는 대표적으로 `크루스칼`과 `프림`이 있다.
다익스트라와 비슷한 형태인 `프림` 알고리즘으로 MST 문제를 푸는 것을 선호하지만 `프림` 알고리즘의 경우 정점간의 인접 관계가 필요하다. 위 문제의 경우 정점의 인접관계를 얻기 위해서는 입력을 추가적으로 가공해야하므로 `크루스칼` 알고리즘을 이용했다.
같이 보면 좋은 문제: [백준 - 1197] 최소 스패닝 트리
'Problem Solving > Programmers' 카테고리의 다른 글
[프로그래머스 - 148653] 마법의 엘리베이터 - C++ (0) | 2023.10.17 |
---|---|
[프로그래머스 - 49189] 가장 먼 노드 - C++ (1) | 2023.10.11 |
[프로그래머스 - 12936] 줄 서는 방법 - C++ (1) | 2023.10.05 |
[프로그래머스 - 67259] [카카오 인턴] 경주로 건설 - C++ (1) | 2023.10.03 |
[프로그래머스 - 43164] 여행경로 - Python (0) | 2023.09.11 |