n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.
다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.
제한 사항
입출력 예

입출력 예 설명
costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다.

섬 연결하기 문제를 풀이하기 위해서는 유니온-파인드와 크루스칼에 대해 알아야 한다.
먼저 유니온 파인드(Union Find) 알고리즘은 유니온이라는 함수와 파인드라는 두 함수가 연결되어 있는 것과 같다.
어디와 어디가 연결되어 있는지 알고 싶을 때 사용하는 것이 유니온 파인드 알고리즘 이다.
크루스칼(Kruskal) 알고리즘은 그래프의 최소 신장 트리(Minimum Spanning Tree, MST)를 찾는 알고리즘 중 하나이다. 최소 신장 트리란 그래프의 모든 노드를 연결하는 에지들의 가중치 합이 최소가 되는 트리를 말한다. 크루스칼 알고리즘은 탐욕적인 방법(greedy method)을 사용하여 문제를 해결한다.
크루스칼 알고리즘은 다음과 같은 단계로 수행된다.
이제 두 알고리즘을 사용하여 문제를 풀어보자.
처음엔 아무것도 연결되어 있지 않은 상태이므로 각 노드가 모두 대표 노드이다. 따라서 자신의 인덱스값으로 초기화 해준다.
parent = [0] * n
for i in range(n):
parent[i] = i
이 부분은 union으로 각 노드가 속한 집합을 1개로 합치는 코드이다.
def setUnion(parent, a, b):
fa = findParent(parent, a)
fb = findParent(parent, b)
if fa == fb:
return
else:
parent[fb] = fa
이 부분은 find로 특정 노드 x에 관해 x가 속한 집합의 부모 노드를 반환하는 코드이다.
def findParent(parent, x):
if parent[x] == x:
return x
else:
return findParent(parent, parent[x])
이 부분이 크루스칼을 이용해서 최소 비용을 구하는 코드이다.
costs.sort(key=lambda x: x[2])
for a, b, cost in costs:
if findParent(parent, a) != findParent(parent, b):
setUnion(parent, a, b)
answer += cost
return answer
def findParent(parent, x):
if parent[x] == x:
return x
else:
return findParent(parent, parent[x])
def setUnion(parent, a, b):
fa = findParent(parent, a)
fb = findParent(parent, b)
if fa == fb:
return
else:
parent[fb] = fa
def solution(n, costs):
answer = 0
parent = [0] * n
for i in range(n):
parent[i] = i
costs.sort(key=lambda x: x[2])
for a, b, cost in costs:
if findParent(parent, a) != findParent(parent, b):
setUnion(parent, a, b)
answer += cost
return answer