벨만-포드 알고리즘은 그래프에서 최단 거리를 구하는 알고리즘으로, 특정 출발 노드에서 다른 모든 노드까지의 최단 경로를 탐색한다. 다익스트라 알고리즘과 다른 점은 음수 가중치 에지가 있어도 수행할 수 있다는 것이다. 또한 전체 그래프에서 음수 사이클의 존재 여부를 판단할 수 있다.
시간복잡도: O(VE) V(노드 수) E(에지 수)
업데이트 조건과 방법
D[s]가 무한대가 아니며 D[e](종료하고 있는 최단경로 리스트 값) > D[s](시작하는 최단경로 리스트 값) + w(가중치)일 때 D[e] = D[s] + w로 리스트의 값을 업데이트한다.
음수 사이클 유무 확인하는 방법
N-1번 돌렸을 때보다 한 번 더 돌렸을 때인 N번 돌렸을 때 가중치가 더 작아진다면 음수 사이클이 존재한다는 것이다. 음수 사이클이 존재하면 이 사이클을 무한하게 돌수록 가중치가 계속 감소하므로 최단 거리를 구할 수 없다. 아래 그래프에서 D[4] = 10이고 D[5] = 11이다. D[5] + w < D[4]이므로 D[4]의 값이 업데이트 된다. 그러므로 벨만-포드 알고리즘을 사용할 때는 N-1번의 에지로 업데이트를 통해서 최단거리를 구할 수 있어야 하고 한 번 더 업데이트를 해서 업데이트가 이루어지면 안되는 것이다.
import sys
INF = sys.maxsize
input = sys.stdin.readline
n,m = map(int,input().split())
edges = []
distance = [INF] * (n+1)
for _ in range(m):
s,e,cost = map(int,input().split())
edges.append((s,e,cost))
# 시작점 거리 0으로 초기화
distance[1] = 0
# 시작점이 무한대가 아니고 D[e] > D[s] + w일 경우에 업데이트
for _ in range(n-1):
for s,e,cost in edges:
if distance[s] != INF and distance[e] > distance[s] + cost:
distance[e] = distance[s] + cost
# 음수 사이클 확인
Minus_Cycle = False
for s,e,cost in edges:
if distance[s] != INF and distance[e] > distance[s] + cost:
Minus_Cycle = True
if Minus_Cycle:
print(-1)
else:
for i in range(2, n+1):
if distance[i] == INF:
print(-1)
else:
print(distance[i])
출처
Do it algorithm