출처
https://programmers.co.kr/learn/courses/30/lessons/42861
문제
n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.
다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.
입출력 예 설명
costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다.
제한
- 섬의 개수 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 |
해석
다행히 연결할 수 없는 섬은 주어지지 않으므로, 시작점을 어디를 잡아도 된다. 그래서 0번째 마을을 기준으로 코드를 작성하였다. 섬을 방문했는 지를 알려주는 vi라는 리스트를 만들어서, 만약 아직 안갔다면 True를, 갔었다면 False로 나타내어준다. 0번 째 섬을 기준으로 현재 갈 수 있는 섬들을 알려주는 리스트로 li를 사용하였다. 다만,heapq를 사용한 이유는 최소 비용을 지불해야하므로 비용을 기준으로 heappush를 해주기 위해서 사용하였다. 그렇게 모든 구역을 다 돌 때까지(0번째 마을을 시작으로 li가 없어질 때까지 혹은 vi리스트 값이 모두 False가 될 떄까지로 설정하면 될 것이다.) 반복하여 주면 된다.
소스 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
def solution(n, costs):
answer = 0
vi = list(True for _ in range(n))
town = defaultdict(list)
for i in costs:
town[i[0]].append([i[1], i[2]])
town[i[1]].append([i[0], i[2]])
# 시작점의 위치를 0
vi[0] = False
li = []
# 0에서 이동할 수 있는 곳을 li에 저장한다. 가장 짧은 길로 가면 되므로 길을 기준으로 heappush해준다.
for i in town[0]:
heapq.heappush(li, [i[1], i[0]])
# 모든 길은 연결 되어 있으므로, 모든 길을 다 돌때까지 실행하면 된다.
while li:
length, dest = heapq.heappop(li)
if vi[dest]:
vi[dest] = False
answer += length
for i in town[dest]:
heapq.heappush(li, [i[1], i[0]])
return answer
|
cs |