다익스트라 알고리즘을 사용해 최단 경로를 얻어내고, BFS를 통해 최단 경로에 사용된 간선을 제거할 수 있다. 이후 다익스트라 알고리즘을 사용하면서 (이때 이전의 간선은 사용할 수 없다) 거의 최단 경로를 얻는다.
distances
에 기록된 비용과 일치한다면 곧 최단 경로를 얻는 데 사용한 노드라는 점이다. 즉 distances[post_node] + post_cost == distances[cur_node]
.path
로 리스트 자체를 BFS에 넣어서 전달해서 비활성화했는데, 이 경우 메모리 초과가 났기 때문에 방향 그래프 자체를 거꾸로 만든 뒤 도착지에서 목적지로 향하면서 최단 경로가 맞는지 확인해야 했다. 이런 접근법을 기억하자.import sys
import heapq
from collections import deque
INF = sys.maxsize
while True:
n, m = map(int, sys.stdin.readline().rstrip().split())
if n == 0 and m == 0: break
nodes = [[] for _ in range(n)]
nodes_inv = [[] for _ in range(n)]
edges = [[False for _ in range(n)] for _ in range(n)]
s, d = map(int, sys.stdin.readline().rstrip().split())
for _ in range(m):
u, v, p = map(int, sys.stdin.readline().rstrip().split())
nodes[u].append([v, p])
nodes_inv[v].append([u, p])
def Dijstra():
distances = [INF for _ in range(n)]
distances[s] = 0
pq = []
heapq.heappush(pq, [0, s])
while pq:
cur_cost, cur_node = heapq.heappop(pq)
if distances[cur_node] < cur_cost: continue
for next_node, next_cost in nodes[cur_node]:
if edges[cur_node][next_node]: continue
if distances[next_node] > next_cost+cur_cost:
distances[next_node] = next_cost+cur_cost
heapq.heappush(pq, [next_cost+cur_cost, next_node])
return distances
def BFS():
queue = deque()
queue.append(d)
while queue:
cur_node = queue.popleft()
if cur_node == s: continue
for post_node, post_cost in nodes_inv[cur_node]:
if distances[post_node] + post_cost == distances[cur_node] and not edges[post_node][cur_node]:
# cur_node로 향하는 이전 간선 비용을 사용했을 때 distances에 기록된 비용이라면 곧 최단 경로에 사용했다는 뜻이다.
edges[post_node][cur_node] = True
queue.append(post_node)
distances = Dijstra()
BFS()
distances = Dijstra()
if distances[d] == INF: print(-1)
else: print(distances[d])