본문 바로가기
Algorithm/Baekjoon

11779. 최소비용 구하기 2 (Python)

by 원만사 2022. 5. 30.
반응형
 

11779번: 최소비용 구하기 2

첫째 줄에 도시의 개수 n(1≤n≤1,000)이 주어지고 둘째 줄에는 버스의 개수 m(1≤m≤100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스

www.acmicpc.net

 

풀이

 출발지가 주어졌고 비용에 음수가 없으므로 다익스트라를 이용하여 출발지에서 도착지까지의 최단 거리를 구할 수 있다. 다익스트라는 링크를 참고하자.

 

 문제에서는 단순히 최단 거리뿐만 아니라 경로까지 요구하고 있다. 이를 위해 prev라는 리스트를 추가하였다. prev[x]는 출발지에서 x까지 최단 거리로 이동할 때 x 지점에 도착하기 이전에 방문했던 지점에 대한 정보를 담고 있다. 예를 들어 start -> a -> b -> x와 같은 경로로 이동했다면 prev[x]에는 b라는 지점을 저장하고 있는 것이다. 

 이와 같이 바로 이전에 방문한 지점 정보를 저장한 후 도착지에서 시작하여 출발지를 만나기 전까지 역으로 이전에 방문한 지점을 추적하면 출발지에서 도착지까지 최단 거리로 가는 경로를 구할 수 있다.

 

코드

import sys
import heapq
input = sys.stdin.readline
INF = float('inf')


# 다익스트라
def dijkstra(start):
    q = []
    heapq.heappush(q, (0, start))
    dist[start] = 0
    prev[start] = start  # 시작 지점의 이전 도시는 자기 자신으로 설정

    while q:
        nowDist, city = heapq.heappop(q)

        if dist[city] < nowDist:
            continue

        for nextCity, nextDist in buses[city]:
            totalDist = nowDist + nextDist

            # 최단 거리가 갱신되면
            if totalDist < dist[nextCity]:
                dist[nextCity] = totalDist
                heapq.heappush(q, (totalDist, nextCity))
                prev[nextCity] = city  # 다음 도시의 이전 경로를 현재 도시로 설정


if __name__ == '__main__':
    N = int(input())  # 도시의 개수
    M = int(input())  # 버스의 개수
    buses = [[] for _ in range(N+1)]  # 버스 정보
    dist = [INF for _ in range(N+1)]  # 시작 지점에서 다른 지점까지의 최단 거리
    # prev[x] : 시작 지점에서 x 지점까지 최단 거리로 갈 때, x 지점 바로 이전에 들렀던 지점
    prev = [x for x in range(N+1)]

    # 버스 정보 입력
    for _ in range(M):
        a, b, c = map(int, input().split())
        buses[a].append((b, c))

    start, destination = map(int, input().split())  # 출발지, 도착지

    dijkstra(start)  # 다익스트라 수행
    path = [destination]  # 출발지에서 도착지까지의 경로
    nowCity = destination  # 도착지에서 출발지까지 역으로 추적

    while True:
        prevCity = prev[nowCity]  # nowCity로 갈 때 이전에 들렀던 지점
        path.append(prevCity)  # 경로에 추가

        if prevCity == start:  # 시작 지점을 만나면 while문 종료
            break

        nowCity = prevCity

    path.reverse()  # 역으로 추적했으므로 reverse를 통해 뒤집는다.

    print(dist[destination])
    print(len(path))
    print(*path)
반응형

'Algorithm > Baekjoon' 카테고리의 다른 글

10282. 해킹 (Python)  (0) 2022.06.03
1082. 방 번호 (Python)  (0) 2022.06.02
14938. 서강그라운드 (Python)  (0) 2022.05.30
12851. 숨바꼭질 2 (Python)  (0) 2022.05.29
2263. 트리의 순회 (Python)  (0) 2022.05.27

댓글