전공/프로그래머스
합승 택시 요금
yha97
2023. 10. 9. 21:06
날짜 : 2023. 10. 09
사용 언어 : python
문제
코드
다익스트라
import heapq
INF = int(1e9)
def solution(n, s, a, b, fares):
graph = [[] for _ in range(n + 1)]
for edge in fares: # 각 노드와 연결된 edge 체크
p, q, cost = edge
graph[p].append([q, cost])
graph[q].append([p, cost])
def dijkstra(start, end):
dist = [INF] * (n + 1)
dist[start] = 0 # 현재노드
queue = list()
heapq.heappush(queue, [0, start])
while queue:
d, now = heapq.heappop(queue) # 저장된 노드 체크
if dist[now] < d: # 기존 start ~ now 거리와 비교
continue
for edge in graph[now]: # now와 연결된 edge 체크
cost = d + edge[1]
if cost < dist[edge[0]]:
dist[edge[0]] = cost
heapq.heappush(queue, [cost, edge[0]]) # 다음에 이동할 노드, 그 노드까지의 거리 저장
return dist[end] # start에서 도착지까지의 최소값
res = dijkstra(s, a) + dijkstra(s, b)
for via in range(1, n + 1):
if via == s: continue
res = min(res, dijkstra(s, via) + dijkstra(via, a) + dijkstra(via, b))
return res
플로이드-워셜(n의 최대 크기가 200이기 때문에 사용 가능)
def solution(n, s, a, b, fares):
INF = int(1e9)
graph = [[INF] * (n + 1) for _ in range(n + 1)]
for edge in fares:
n1, n2, cost = edge
graph[n1][n2] = cost
graph[n2][n1] = cost
for i in range(n + 1): graph[i][i] = 0 # 자기 자신을 향한 거리는 무조건 0
for via in range(1, n + 1):
for start in range(1, n + 1):
for end in range(1, n + 1):
graph[start][end] = min(graph[start][end], graph[start][via] + graph[via][end])
res = graph[s][a] + graph[s][b] # 합승하지 않은 루트
for via in range(1, n + 1):
res = min(res, graph[s][via] + graph[via][a] + graph[via][b]) # 합승하여 이동
return res
풀이
- start -> end 까지의 최단거리를 구하는 다익스트라 함수를 구현한 다음, 합승하지 않은 경우의 수인 res를 설정한다.
- 이후 노드 1부터 n까지 체크하면서 합승한 케이스를 다익스트라를 사용해 최소값을 갱신한 후 값을 리턴한다.
알게된 점
- 다익스트라를 구현해 곧바로 풀 수 있었던 문제였다.
- 주어진 루트를 2차원 그래프로 변환하는 것과 경로를 찾는 알고리즘을 사용해 활용하는 아이디어를 떠올리는 것이 골자였다.
- 플로이드-워셜의 구현이 확실히 쉬웠고 해당 문제는 노드의 최대 개수가 200개밖에 되지 않아 O(n^3)도 가능했었다.
- 다만 마지막에 본인이 본인 노드를 가는 케이스를 0으로 초기화하지 않는 바람에 테스트케이스3에서 계속 오류가 발생했었다.
- 여러모로 다익스트라와 플로이드-워셜 구현 연습을 할 필요성을 느끼게 해 주는 문제였다.
참고 사이트
-