728x90
시간 제한 1초, 메모리 제한 1024MB
# 조건
코로나로 인하여 확찐자가 되버려 오늘부터 산책을 하려고 한다. 이를 위해 산책할 경로를 정하려고 한다.
현재 있는 곳 $S$에서 출발하여 $S$와 다른 곳인 $E$를 찍고 다시 $S$로 돌아오는 경로로 만들려고 한다. 산책을 할 때 이미 갔던 정점을 또 가기 싫어 $E$에서 $S$로 올 때 $S$에서 $E$로 가는 도중에 방문한 정점을 제외한 다른 정점으로 이동하려고 한다. 또한 산책 거리가 긴 것을 싫어하여 $S$에서 $E$로 가는 가장 짧은 거리와 $E$에서 $S$로 가는 가장 짧은 거리를 원한다.
정점 $S$에서 정점 $E$로 이동할 때, 가장 짧은 거리의 경로가 여러개 나올 수 있다. 그 중, 정점 $S$에서 정점 $E$로 이동한 경로를 나열했을 때, 사전순으로 가장 먼저 오는 것을 선택한다.
예를 들어, 정점 1에서 정점 2로 이동한다고 했을 때, 가장 짧은 거리의 경로가 1 4 3 2
와 1 3 4 2
가 있다고 가정을 해보자. 두 개의 경로중 사전순으로 먼저 오는 것은 1 3 4 2
이므로 정점 1에서 정점 2로 가는 최단 경로 중 두 번째 것을 선택한다.
이와 같이 산책 경로를 정할 때, 산책 전체 경로의 거리($S$에서 $E$로 가는 거리 + $E$에서 $S$로 가는 거리)를 구해보자.
# 접근 방법
- 출발지에서 목적지에 도착한 후 다시 출발점으로 돌아오는 최소의 경로를 구하면 되기에 2번의 다익스트라를 활용하여 풀어주었다.
- 이 때 주의할 점은 출발지에서 목적지로 가는 최소 경로가 여러 개인 경우 경유하는 정점의 번호가 사전순으로 빠른 길을 선택하면 된다.
- 이 작업을 위해서 각 노드들의 연결 관계를 sort로 정렬해주었다.
- 이후 다익스트라 함수를 수행해주는데 출발지에서 목적지로 가는 첫 번째 행동의 경우 dist[st]를 0으로 만들고, S와 E를 그대로 넣어준다.
- 또한, Q에는 **누적 가중치, [현재까지의 경로]를 넣어준다.
- 도착지에 도착했다면 RETURN 받은 비용을 result에 더해주고, dist 배열을 초기화, route에 표시된 곳을 0으로 변경해준 후 E와 S를 반대로 넣어 다시 수행해주면 된다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
from heapq import heappop, heappush
def dijkstra(st, en):
q = []
heappush(q, [0, [st]])
while q:
val, route = heappop(q)
if route[-1] == en:
return val, route
if dist[route[-1]] < val:
continue
for n in node[route[-1]]:
if dist[n] > val + 1:
heappush(q, [val+1, route + [n]])
dist[n] = val+1
N, M = map(int, input().split())
node = [[] for _ in range(N+1)]
for _ in range(M):
a, b = map(int, input().split())
node[a].append(b)
node[b].append(a)
for i in range(N+1):
node[i].sort()
S, E = map(int, input().split())
result = 0
dist = [float('inf')] * (N + 1)
r = []
for i in range(2):
if i == 0:
dist = [float('inf')] * (N + 1)
dist[S] = 0
v, r = dijkstra(S, E)
result += v
else:
dist = [float('inf')] * (N + 1)
for j in r:
dist[j]= 0
dist[E] = 0
dist[S] = float('inf')
v,r = dijkstra(E, S)
result += v
print(result)
728x90
'ALGORITHM > 다익스트라, 벨만포드, 플로이드워셜' 카테고리의 다른 글
[백준 5972번] 파이썬 - 택배 배송 (0) | 2024.09.02 |
---|---|
[백준 18223번] 파이썬 - 민준이와 마산 그리고 건우 (2) | 2024.01.23 |
[백준 15723번] 파이썬 - n단 논법 (0) | 2024.01.19 |
[백준 10844번] 파이썬 - 쉬운 계단 수 (0) | 2023.11.13 |
[백준 2665번] 파이썬 - 미로 만들기 (0) | 2023.11.12 |