https://school.programmers.co.kr/learn/courses/30/lessons/42861
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 설명
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의 비용이 주어지지 않습니다.
- 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.
- 연결할 수 없는 섬은 주어지지 않습니다.
풀이
# 프림
def solution(n, costs):
from heapq import heappush, heappop
from collections import defaultdict
min_cost = cnt = 0
visited = set()
heap = []
link_info = defaultdict(list)
for num1, num2, cost in costs:
link_info[num1].append((cost, num2))
link_info[num2].append((cost, num1))
for i in range(n+1):
if link_info.get(i):
visited.add(i)
for element in link_info[i]:
heappush(heap, element)
break
while cnt < n-1:
cost, num = heappop(heap)
if num not in visited:
visited.add(num)
min_cost += cost
cnt += 1
for element in link_info[num]:
if element[1] not in visited:
heappush(heap, element)
if not heap:
break
return min_cost
'''
정확성 테스트
테스트 1 〉 통과 (0.01ms, 10.2MB)
테스트 2 〉 통과 (0.02ms, 10.1MB)
테스트 3 〉 통과 (0.03ms, 10.2MB)
테스트 4 〉 통과 (0.07ms, 10.1MB)
테스트 5 〉 통과 (0.03ms, 10MB)
테스트 6 〉 통과 (0.05ms, 10.3MB)
테스트 7 〉 통과 (0.06ms, 10.1MB)
테스트 8 〉 통과 (0.03ms, 10.2MB)
'''
# 크루스칼
def solution(n, costs):
min_cost = cnt = i = 0
root_of = list(range(n))
rank = [1] * n
costs.sort(key=lambda cost: cost[2])
def find_root(num):
if root_of[num] == num:
return num
result = find_root(root_of[num])
root_of[num] = result
return result
def has_same_root(num1, num2):
root1, root2 = find_root(num1), find_root(num2)
if root1 == root2:
return True
if rank[root1] <= rank[root2]:
rank[root2] += rank[root1]
root_of[root1] = root2
else:
rank[root1] += rank[root2]
root_of[root2] = root1
return False
while cnt < n-1:
num1, num2, cost = costs[i]
if not has_same_root(num1, num2):
min_cost += cost
cnt += 1
i += 1
return min_cost
'''
정확성 테스트
테스트 1 〉 통과 (0.01ms, 10.3MB)
테스트 2 〉 통과 (0.02ms, 10.2MB)
테스트 3 〉 통과 (0.03ms, 10.2MB)
테스트 4 〉 통과 (0.03ms, 10.2MB)
테스트 5 〉 통과 (0.02ms, 10.3MB)
테스트 6 〉 통과 (0.03ms, 10.2MB)
테스트 7 〉 통과 (0.05ms, 10.2MB)
테스트 8 〉 통과 (0.02ms, 10.1MB)
'''
'문제 풀이 > Python' 카테고리의 다른 글
[BOJ / solved ac] 1976 여행 가자 (0) | 2023.08.27 |
---|---|
[BOJ / solved ac] 18116 로봇 조립 (0) | 2023.08.26 |
[BOJ/solved ac] 2660 회장 뽑기 (0) | 2023.08.20 |
[Python] [BOJ] 2156 포도주 시식 (0) | 2023.05.28 |
[Python] [BOJ] 13549 숨바꼭질 3 (0) | 2023.05.27 |