-
백준 #1916 - 최소비용 구하기알고리즘 2024. 4. 29. 11:50
문제
N개의 도시가 있다. 그리고 한 도시에서 출발하여 다른 도시에 도착하는 M개의 버스가 있다. 우리는 A번째 도시에서 B번째 도시까지 가는데 드는 버스 비용을 최소화 시키려고 한다. A번째 도시에서 B번째 도시까지 가는데 드는 최소비용을 출력하여라. 도시의 번호는 1부터 N까지이다.
입력
첫째 줄에 도시의 개수 N(1 ≤ N ≤ 1,000)이 주어지고 둘째 줄에는 버스의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 M+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가 주어진다. 그리고 그 다음에는 도착지의 도시 번호가 주어지고 또 그 버스 비용이 주어진다. 버스 비용은 0보다 크거나 같고, 100,000보다 작은 정수이다.
그리고 M+3째 줄에는 우리가 구하고자 하는 구간 출발점의 도시번호와 도착점의 도시번호가 주어진다. 출발점에서 도착점을 갈 수 있는 경우만 입력으로 주어진다.
출력
첫째 줄에 출발 도시에서 도착 도시까지 가는데 드는 최소 비용을 출력한다.
예제 입력
5 8 1 2 2 1 3 3 1 4 1 1 5 10 2 4 2 3 4 1 3 5 1 4 5 3 1 5
예제 출력
4
오... 이번건 모르겠어서 인터넷의 도움을 많이 받았다.
일단 heap 자료구조부터 살펴보자.
힙(Heap) 이란?
: 최댓값과 최솟값을 빠르게 찾기 위해 고안된 자료구조
- 각 노드의 key값이 해당 노드의 자식노드의 key값보다 작지 않거나 크지 않은 완전 이진트리
- 키 값의 대소관계는 부모-자식 노드 사이 간에만 성립하며 형제 노드 사이에는 영향을 미치지 않음
- 자식노드의 최대 개수는 힙의 종류에 따라 다르지만 이진트리에서는 최대 2개 (완전이진트리를 사용한다고 가정하자.)
- i번째 노드의 자식노드가 2개인데 왼쪽 자식노드는 2i, 오른쪽 자식노드는 2i+1이고, 부모노드는 i/2가 된다.
최대 힙 (max heap)
: 각 노드의 키 값이 그 자식노드의 키 값보다 작지 않은 힙
최소 힙 (min heap)
: 각 노드의 키 값이 그 자식노드의 키 값보다 크지 않은 힙
그렇다면 다익스트라 알고리즘은?
다익스트라 알고리즘이란?
: 최단거리 알고리즘
- 하나의 노드에서 다른 모든 노드까지의 거리를 구할 수 있음
- 최단거리를 구할 노드에서 시작하여, 거리가 입력된 노드 중 최단거리가 가장 작은 노드를 돌아가며 선택
- 노드를 돌아가면서, 더 거리가 짧은 나오면 값을 갱신하여 넣기
- 이때, 초기에는 모든 거리를 무한으로 설정하기
from heapq import heappop, heappush import sys input = sys.stdin.readline n = int(input()) # 도시의 개수 m = int(input()) # 버스의 개수 INF = 1e9 buses = [[] for _ in range(n + 1)] # 버스 정보 저장 리스트 dp = [INF for _ in range(n + 1)] # 각 도시에 도착하는 최소비용 리스트 (초기에는 무한값 넣기) for i in range(m): a, b, c = list(map(int, input().split())) # 출발도시, 도착도시, 비용 buses[a].append((b, c)) # 출발도시 인덱스에 도착도시와 비용 저장 start, end = map(int, input().split()) # 목표시작점, 목표끝점 # 다익스트라 def dijkstra(x): dp[x] = 0 # 시작점이므로 0의 비용으로 도착 heap = [] heappush(heap, [0, x]) # 비용과 현재 좌표 리스트로 힙에 값 넣기 while heap: cost, point = heappop(heap) # 비용, 현재 좌표 if dp[point] < cost: # dp 리스트의 현재 좌표까지 오는 비용이 지금까지 비용보다 적다면 continue # 넘어감 for fin, money in buses[point]: #현재 좌쵸에서 출발하는 경로 순회 new_cost = cost + money # 비용 더하기 if dp[fin] > new_cost: # 지금까지 든 비용보다 작다면 dp[fin] = new_cost # 값 갱신 heappush(heap, [new_cost, fin]) # 새로운 비용과 현재 좌표 힙에 넣기 dijkstra(start) print(dp[end]) # dp 리스트의 도착지까지 가는 비용 출력
'알고리즘' 카테고리의 다른 글
백준 #7576 - 토마토 (0) 2024.05.04 백준 #1946 - 신입 사원 (0) 2024.05.04 백준 #2225 - 합분해 (0) 2024.04.29 백준 #11659 - 구간 합 구하기 4 (0) 2024.04.27 백준 #2193 - 이친수 (0) 2024.04.26