최단 경로 알고리즘
그래프 상에서 노드 간의 탐색 비용을 최소화하는 알고리즘이다세 가지 최단 경로 알고리즘
1. 다익스트라
2. 벨만 포드
3. 플로이드 워셜
for k in range(1, V+1): # via
graph[k][k] = 0 # 사이클이 없으므로 자기자신 = 0
for i in range(1, V+1): # src
for j in range(1, V+1): # dst
graph[i][j] = min(graph[i][j], graph[i][k]+graph[k][j])
def dijkstra(start) :
q = [] # 큐가 사용할 공간
heapq.heappush(q,(0,start)) # Start 데이터 push
distance[start] = 0 # 최단경로테이블 최적해 갱신
while q : # 큐가 비어질때까지 반복
cost,node = heapq.heappop(q) #우선순위가 높은 데이터 POP ( 비용, 현재노드 )
# 이미 방문한 노드인 경우
if distance[node] < cost : continue
for next in graph[node] :
next_cost = next[1] + cost
if next_cost < distance[next[0]] :
distance[next[0]] = next_cost #최단경로 테이블 최적해로 갱신
heapq.heappush(q,(next_cost,next[0])) # 데이터 우선순위큐에 PUSH
시간복잡도:
def bellman_ford(start):
# 시작 노드에 대해서 초기화
distance[start] = 0
# 전체 v - 1번의 라운드(round)를 반복
for i in range(v):
# 매 반복마다 '모든 간선'을 확인한다.
for j in range(e):
cur_node = edges[j][0]
next_node = edges[j][1]
edge_cost = edges[j][2]
# 현재 간선을 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우
if distance[cur_node] != INF and distance[next_node] > distance[cur_node] + edge_cost:
distance[next_node] = distance[cur_node] + edge_cost
# v번째 라운드에서도 값이 갱신된다면 음수 순환이 존재
if i == v - 1:
return True
개선된 다익스트라 사용
PriorityQueue 사용 X -> 시간 초과
V*V의 2차원 그래프 -> 메모리 초과
import sys
from queue import PriorityQueue
inf = sys.maxsize
input = sys.stdin.readline
V, E = map(int, input().split())
K = int(input())
graph = [[] * (V+1) for _ in range(V+1)]
for _ in range(E):
u, v, w = map(int, input().split())
graph[u].append((v, w))
# if graph[u][v] > w:
# graph[u][v] = w
dijstra = [inf] * (V+1)
dijstra[K] = 0
que = PriorityQueue()
que.put((0, K))
while not que.empty():
weight, node = que.get()
# 갱신
if dijstra[node] < weight:
continue
# node와 연결된 다른 노드들을 큐에 삽입
# for i in range(V):
for next, edge in graph[node]:
next_weight = weight + edge
if dijstra[next] > next_weight:
dijstra[next] = next_weight
que.put((next_weight, next))
for i in range(1, V+1):
if dijstra[i] == inf:
print("INF")
else:
print(dijstra[i])
import sys
inf = sys.maxsize
input = sys.stdin.readline
N, M = map(int, input().split())
edges = []
for _ in range(M):
a, b, c = map(int, input().split())
edges.append((a, b, c))
dist = [inf]*(N+1)
dist[1] = 0
# N-1 번 반복
for i in range(N):
# 모든 간선 확인
for cur, next, cost in edges:
if dist[cur] != inf and dist[cur] + cost < dist[next]:
dist[next] = dist[cur]+cost
# 만약 N 번째에 갱신이 있다면 음의 사이클이 있다는 것.
if i == N-1:
print(-1)
exit(0)
for i in range(2, N+1):
if dist[i] == inf:
print(-1)
else:
print(dist[i])
<BAEKJOON: 골드 5> 최소비용 구하기
<BAEKJOON: 골드 4> 알고스팟
<BAEKJOON: 골드 4> 특정한 최단 경로
<BAEKJOON: 골드 3> 파티
<BAEKJOON: 골드 2> 미확인 도착지
<BAEKJOON: 골드 4> 데이터 만들기 3
<BAEKJOON: 골드 3> 웜홀
<BAEKJOON: 골드 2> The Mountain of Gold?
<BAEKJOON: 골드 1> 골목길
<BAEKJOON: 플레티넘 5> 오민식의 고민
<BAEKJOON: 실버 1> n단 논법
<BAEKJOON: 골드 5> 회장뽑기
<BAEKJOON: 골드 4> 서강그라운드
<BAEKJOON: 골드 4> 구슬 찾기
<BAEKJOON: 골드 2> 플로이드 2