Search

PGS 합승 택시 요금

태그
그래프 이론
그래프 탐색
최단 경로
데이크스트라
생성일
2025/03/04 03:03

문제 설명

출발지점 s에서 두 사람이 각각 a, b로 이동할 때, 합승을 포함한 모든 경로 중 최소 택시 요금을 계산하는 문제

예제 입력/출력

n
s
a
b
fares
result
6
4
6
2
[[4, 1, 10], [3, 5, 24], [5, 6, 2], [3, 1, 41], [5, 1, 24], [4, 6, 50], [2, 4, 66], [2, 3, 22], [1, 6, 25]]
82
7
3
4
1
[[5, 7, 9], [4, 6, 4], [3, 6, 1], [3, 2, 3], [2, 1, 6]]
14
6
4
5
6
[[2,6,6], [6,3,7], [4,6,7], [6,5,11], [2,5,12], [5,3,20], [2,4,8], [4,3,9]]
18

제약 조건

3n2003 ≤ n ≤ 200
1s,a,bn1 ≤ s, a, b ≤ n
2faresn×(n1)/22 ≤ |fares| ≤ n \times (n-1) / 2
fares 배열의 각 행은 [c, d, f] 형태
1c,dn1 ≤ c, d ≤ n
1f100,0001 ≤ f ≤ 100,000

문제 풀이

출발지점(S)과 도착 지점(A, B)이 정해져 있다.
혼자 택시를 탑승한다 → 출발지점에서 출발하여 다른 지점을 거치지 않고 바로 A, B 지점으로 가는 경우의 비용을 계산한다.
합승한다 → 하나의 지점(K)을 거치고 A, B 지점으로 각각 이동하는 경우의 비용을 계산한다.
따라서 출발점 S에서 모든 노드까지의 최단 거리를 계산해야 한다.
이를 위해 플로이드 워셜 혹은 다익스트라 알고리즘을 사용한다.
접근1 플로이드-워셜 - O(N3)O(N^3)
각 노드 k를 중간 경유지로 설정하여, 모든 노드 쌍 (i, j) 간 최단 거리를 갱신한다.
모든 노드 간 최단 거리를 미리 구한 후, S → TT → AT → B의 최소 비용을 구한다.
접근2 다익스트라 - O(3(N+E)logN)O(3(N+E) \cdot logN)
이 문제에서는 특정 출발점에서의 최단 거리만 필요하기 때문에 다익스트라 알고리즘을 활용하면 더 효율적으로 해결할 수 있다.
다익스트라 알고리즘을 세 번만 실행하면 된다.
1.
S에서 모든 노드까지의 최단 거리 → dist_from_s
2.
A에서 모든 노드까지의 최단 거리 → dist_from_a
3.
B에서 모든 노드까지의 최단 거리 → dist_from_b

풀이 코드

접근1 플로이드-워셜 - O(N3)O(N^3)
import heapq INF = int(1e9) def solution(n, s, a, b, fares): dists = [[INF] * (n + 1) for _ in range(n + 1)] # 거리 행렬 초기화 for i in range(1, n + 1): for j in range(1, n + 1): if i == j: dists[i][j] = 0 for c, d, f in fares: dists[c][d] = f dists[d][c] = f # 플루이드워셜 알고리즘 for k in range(1, n + 1): for i in range(1, n + 1): for j in range(1, n + 1): dists[i][j] = min(dists[i][j], dists[i][k] + dists[k][j]) ans = INF for t in range(1, n + 1): ans = min(ans, dists[s][t] + dists[t][a] + dists[t][b]) return ans
Python
복사
접근2 다익스트라 - O(3(N+E)logN)O(3(N+E) \cdot logN)
import heapq INF = int(1e9) def dijkstra(start): global n, adj_list hq = [] heapq.heappush(hq, (0, start)) # (요금, 노드) dists = [INF] * (n + 1) dists[start] = 0 while hq: cur_cost, cur_node = heapq.heappop(hq) for adj_node, adj_cost in adj_list[cur_node]: tmp_dist = dists[cur_node] + adj_cost if tmp_dist < dists[adj_node]: dists[adj_node] = tmp_dist heapq.heappush(hq, (adj_cost, adj_node)) return dists def solution(_n, s, a, b, fares): global n, adj_list n = _n adj_list = [[] for _ in range(n + 1)] # (노드, 요금) for c, d, f in fares: adj_list[c].append((d, f)) adj_list[d].append((c, f)) dist_from_s = dijkstra(s) dist_from_a = dijkstra(a) dist_from_b = dijkstra(b) ans = INF for i in range(1, n + 1): ans = min(ans, dist_from_s[i] + dist_from_a[i] + dist_from_b[i]) return ans
Python
복사

참고 자료