반응형
<풀이>
"""
1. 아이디어
- 우선 반드시 지나야 하는 두 정점 사이의 최소 거리를 구한다. (다익스트라)
- 그리고 1번 정점과 v1, v2 / N번 정점과 v1, v2 사이의 거리를 구한 뒤 더 짧은 거리를 선택한다.
2. 시간 복잡도
- O(3 * ElgV) = 5 * 200000 * lg(800) =~ 2,903,089 -> 가능
3. 변수
- 정점의 개수, 간선의 개수 : int
- 힙 : (비용, 노드번호)
- 거리배열 : int[]
- 인접 간선 리스트 : (비용, 노드번호)[]
"""
import sys
import heapq
INF = sys.maxsize
input = sys.stdin.readline
N, E = map(int, input().split())
edge = [[] for _ in range(N + 1)]
for _ in range(E):
a, b, c = map(int, input().split())
edge[a].append([c, b])
edge[b].append([c, a])
v1, v2 = map(int, input().split())
def min_dist(start_node, end_node):
heap = [[0, start_node]]
dist = [INF] * (N + 1)
dist[start_node] = 0
while heap:
w, v = heapq.heappop(heap)
if w != dist[v]: continue
for nw, nv in edge[v]:
if dist[nv] > dist[v] + nw:
dist[nv] = dist[v] + nw
heapq.heappush(heap, [dist[nv], nv])
return dist[end_node]
dist_v1_to_v2 = min_dist(v1, v2)
dist_1_to_v1 = min_dist(1, v1)
dist_1_to_v2 = min_dist(1, v2)
dist_v1_to_N = min_dist(v1, N)
dist_v2_to_N = min_dist(v2, N)
total_dist = dist_v1_to_v2 + min(dist_1_to_v1 + dist_v2_to_N, dist_1_to_v2 + dist_v1_to_N)
print(total_dist if total_dist < INF else -1)
고등학교 확통에서 풀던 최단경로의 개념과 유사하다.
1번 정점에서 N번 정점으로 최단경로 이동을 할 때, 반드시 v1, v2 정점을 지나야 하므로
v1, v2 정점 사이의 최단 경로를 구한 뒤 (1번 → v1 + v2 → N번) 과 (1번 → v2 + v1 → N번) 중 더 짧은 거리를 구해 더해주면 된다.
각 정점 사이의 최단 경로는 다익스트라를 통해 구해주었다.
<핵심 정리>
1. 특정 정점을 반드시 지나야 하는 최단 경로 문제의 경우 경로를 쪼개 다익스트라로 해결하면 된다.
2. 더 나아가 특정 정점들을 지나지 않는 최단 경로 문제가 나오는 경우 방문 여부 리스트를 추가해 고려해주는 방식으로 풀 수 있을 것 같다.
반응형
'Base > Algorithm Study' 카테고리의 다른 글
[Python/파이썬] 백준 알고리즘 11657번 - 타임머신 (벨만 포드 알고리즘/Bellman-Ford) (0) | 2023.10.23 |
---|---|
[Python/파이썬] 백준 알고리즘 11053번 - 가장 긴 증가하는 부분 수열 (DP) (0) | 2023.10.12 |
[Python/파이썬] 백준 알고리즘 1753번 - 최단경로 (다익스트라/Dijkstra) (2) | 2022.03.19 |
[Python/파이썬] 백준 알고리즘 10844 - 쉬운 계단 수 (DP) (0) | 2022.03.17 |
[Python/파이썬] 단어 변환 (BFS) (프로그래머스 코딩테스트 고득점 Kit) (0) | 2022.03.16 |