문제를 해결하는데 사용한 알고리즘
- 다익스트라 알고리즘 사용
- 플로이드-워셜 알고리즘으로도 해결 가능
- 전형적인 최단거리 구하는 문제 였음
[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]
밤늦게 귀가할 때 안전을 위해 항상 택시를 이용하던 무지
는 최근 야근이 잦아져 택시를 더 많이 이용하게 되어 택시비를 아낄 수 있는 방법을 고민하고 있습니다. "무지"는 자신이 택시를 이용할 때 동료인 어피치
역시 자신과 비슷한 방향으로 가는 택시를 종종 이용하는 것을 알게 되었습니다. "무지"는 "어피치"와 귀가 방향이 비슷하여 택시 합승을 적절히 이용하면 택시요금을 얼마나 아낄 수 있을 지 계산해 보고 "어피치"에게 합승을 제안해 보려고 합니다.
위 예시 그림은 택시가 이동 가능한 반경에 있는 6개 지점 사이의 이동 가능한 택시노선과 예상요금을 보여주고 있습니다.
그림에서 A
와B
두 사람은 출발지점인 4번 지점에서 출발해서 택시를 타고 귀가하려고 합니다. A
의 집은 6번 지점에 있으며 B
의 집은 2번 지점에 있고 두 사람이 모두 귀가하는 데 소요되는 예상 최저 택시요금이 얼마인 지 계산하려고 합니다.
A
, B
가 합승하여 택시를 이용합니다. 예상 택시요금은 10 + 24 = 34
원 입니다.A
가 혼자 택시를 이용합니다. 예상 택시요금은 2
원 입니다.B
가 혼자 택시를 이용합니다. 예상 택시요금은 24 + 22 = 46
원 입니다.A
, B
모두 귀가 완료까지 예상되는 최저 택시요금은 34 + 2 + 46 = 82
원 입니다.지점갯수 n은 3 이상 200 이하인 자연수입니다.
지점 s, a, b는 1 이상 n 이하인 자연수이며, 각기 서로 다른 값입니다.
A
의 도착지점, B
의 도착지점은 서로 겹치지 않습니다.fares는 2차원 정수 배열입니다.
fares 배열의 크기는 2 이상 n x (n-1) / 2
이하입니다.
6 x 5 / 2 = 15
)출발지점 s에서 도착지점 a와 b로 가는 경로가 존재하는 경우만 입력으로 주어집니다.
S
)이 정해져있고, 도착 지점(A
, B
) 또한 정해져 있다.👉 이때 경우의 수를 생각해보면 출발지점에서 출발하여 다른 지점을 거치지 않고 바로 A
, B
지점으로 가는 경우를 생각해볼 수 있고 (각각 혼자 택시를 탑승하는 경우라고 생각하면 된다)
👉 또는 하나의 지점을 거치고 A
, B
지점으로 가는 경우를 생각해볼 수 있다. 이때 하나의 지점을 거치고 A
, B
로 가게 되는 경우는 하나의 지점까지는 A
, B
가 합승하여 택시를 이용한다고 생각할 수 있다
S
)에서 다른 모든 정점(우리가 구하고자하는 것은 도착지점 A
, B
)으로 가는 최단 경로를 구할 수 있는 다익스트라 알고리즘 또는 플로이드 워셜 알고리즘을 사용하면 된다. import sys, heapq
def solution(n, s, a, b, fares):
INF = sys.maxsize
# 문제에서 주어진 fares를 인접리스트 형태로 바꿈
maps = [[] for _ in range(n+1)]
for v,u,c in fares:
maps[v].append((u, c))
maps[u].append((v, c))
# 다익스트라 알고리즘으로 구현
def dijkstra(start):
distance = [INF] * (n+1)
distance[start] = 0
que = [(0, start)]
while que:
cur_dist, cur_node = heapq.heappop(que)
if distance[cur_node] < cur_dist:
continue
for next_node, next_dist in maps[cur_node]:
if distance[next_node] > cur_dist + next_dist:
distance[next_node] = cur_dist + next_dist
heapq.heappush(que, (cur_dist + next_dist, next_node))
return distance
# i번째(특정 노드)에서 시작해서 모든 정점으로 도착하는 최단거리를 미리 구함
D = [0] + [dijkstra(i) for i in range(1, n+1)]
path = INF
for i in range(1, n+1):
path = min(path, D[s][i] + D[i][a] + D[i][b])
return path
# i번째(특정 노드)에서 시작해서 모든 정점으로 도착하는 최단거리를 미리 구함
D = [0] + [dijkstra(i) for i in range(1, n+1)]
path = INF
for i in range(1, n+1):
path = min(path, D[s][i] + D[i][a] + D[i][b])
👉 우리가 구하고자 하는 최소 거리비용(최저 택시요금)
출발점s에서 i까지의 거리 + i에서 a까지의 거리 + i에서 b까지의 거리
s
(출발점)랑 i
가 같다면 각각 혼자 택시를 탑승하게 되는 경우라 볼 수 있고 만약 s
(출발점)랑 i
가 다르다면 s
부터 i
까지는 A
,B
가 합승하여 택시를 이용하는 거라고 생각할 수 있다.혹시나 잘못된 부분이 있으면 댓글 부탁드립니다.