Algorithm/백준

[백준 알고리즘] 5719번: 거의 최단 경로 (Python)

에릭 Kim 2023. 11. 27. 14:18
반응형

https://www.acmicpc.net/problem/5719 

 

5719번: 거의 최단 경로

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 장소의 수 N (2 ≤ N ≤ 500)과 도로의 수 M (1 ≤ M ≤ 104)가 주어진다. 장소는 0부터 N-1번까지 번호가 매겨져 있

www.acmicpc.net

 

소스코드

import sys
import heapq as hq
from collections import deque
input = sys.stdin.readline

def dijkstra():
  q = []
  min_dis = [float('inf') for _ in range(n)]
  hq.heappush(q,[0,s])
  min_dis[s] = 0 

  while q:
    cur_dis,cur_node = hq.heappop(q)

    if min_dis[cur_node] < cur_dis:
      continue
    for next_node,next_dis in graph[cur_node]:
      if visited[cur_node][next_node]:
        continue
      if min_dis[next_node] > cur_dis + next_dis:
        min_dis[next_node] = cur_dis + next_dis
        hq.heappush(q,[min_dis[next_node],next_node])

  return min_dis

def BFS(): # 목적지 -> 출발지 역방향 탐색
  dq = deque()
  dq.append(d)

  while dq:
    cur_node = dq.popleft()

    if cur_node == s: # 출발점에 도착한 경우 
      continue

    for next_node,next_dis in graph_rev[cur_node]:
      if min_dis[next_node] + next_dis == min_dis[cur_node]:
        if not visited[next_node][cur_node]:
          visited[next_node][cur_node] = True
          dq.append(next_node)

while True:
  n,m = map(int,input().split())
  if n == 0 and m == 0:
    break
  s,d = map(int,input().split())
  graph = [[] for _ in range(n)]
  graph_rev = [[] for _ in range(n)]
  visited = [[False for _ in range(n)] for _ in range(n)]
  for _ in range(m):
    a,b,c = map(int,input().split())
    graph[a].append([b,c])
    graph_rev[b].append([a,c])
  
  min_dis = dijkstra()
  BFS()
  min_dis = dijkstra()
  print(min_dis)
  
  if min_dis[d] == float('inf'):
    print(-1)
  else:
    print(min_dis[d])

 

 

풀이

★ 처음엔 최단 경로로 이동할 때 방문했던 정점들을 기록하고, 역방향으로 이동하면서 그 정점을 제외한 나머지 정점들로 다시 다익스트라를 진행하는 방식으로 접근하였습니다. 하지만 그렇게 된다면 모든 배열을 계속해서 방문하기 때문에 메모리 초과 및 시간초과를 만나게 됩니다. 그렇기에 BFS를 통해 방문한 정점들을 한번에 확인해줘야 합니다 !! 

 

★ 먼저 다익스트라를 수행하면서 목적지에 최단 경로로 이동할 수 있는 경로를 확인해줍니다. 이후 BFS를 돌면서 (이 때 역방향으로 돌아야 하기 때문에 bfs를 도는 시작점은 목적지가 됩니다) 최단 경로를 갈 때 방문했던 정점들을 체크해줍니다. 마지막으로 다시 한번 다익스트라를 돌면서 거의 최단 경로를 찾아줍니다 :) 

반응형