popeye0618

Backend Developer

[python] 백준 - 11657 (타임 머신)

ko 1 조회수 시리즈 · 알고리즘 #알고리즘

문제

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

해결 코드

python
import sys
input = sys.stdin.readline

def bellman_ford(ver, edges, start):
    distance = [float('inf')] * (ver + 1)
    distance[start] = 0

    for i in range(ver - 1):
        for u, v, w in edges:
            if distance[u] != float('inf') and distance[u] + w < distance[v]:
                distance[v] = distance[u] + w

    for u, v, w in edges:
        if distance[u] != float('inf') and distance[u] + w < distance[v]:
            return -1

    for i in range(2, len(distance)):
        if distance[i] == float('inf'):
            distance[i] = -1
    return distance

n, m = map(int, input().split())

edges = []
for _ in range(m):
    u, v, w = map(int, input().split())
    edges.append((u, v, w))

start = 1
result = bellman_ford(n, edges, start)

if result != -1:
    print('\n'.join(map(str, result[2:])))
else:
    print(result)

느낀점

이 문제는 가중치가 있는 그래프를 탐색하는데 그 가중치에 음수도 포함된 경우였다.

음수가 포함되어있기에 다익스트라 알고리즘을 사용할 수 없었다.

다익스트라는 방문하지 않은 간선 중 최소값을 탐색하는데 지나고 나서 음수가 있는 경우에 그 경우는 영영 탐색할 수 없어지기 때문이다.

ex) 2 → 3 이 10의 가중치, 2 → 4 → 3 이 각각 20, -15의 가중치를 가지면 4를 거치는 경우가 더 빠르지만 다익스트라는 탐색 불가

따라서 가중치에 음수가 포함된 경우 벨만-포드 알고리즘을 사용해 해결할 수 있다.

벨만-포드 알고리즘

벨만-포드 알고리즘은 모든 간선을 탐색해서 시작 노드로부터 해당 노드까지의 최단거리를 찾는 알고리즘이다.

모든 간선을 탐색하기에 최대 V-1번 반복하므로 O(VE)의 시간이 걸린다.

다익스트라 알고리즘은 우선순위 큐를 사용하면 O((E + V) log V)의 시간이 걸리므로 다익스트라가 더 빠르다.

하지만 모든 간선을 탐색하기에 모든 경우를 고려할 수 있다는 특징이 있다.

또한 사이클이 있고, 그 사이클의 가중치의 합이 음수인 경우 무한히 음수가 나올 수 있다.

따라서 V-1번 탐색 후 V번째 탐색에서 값 갱신이 한 번 더 나오는 경우 사이클이 있다고 판단할 수 있다.

댓글

0

아직 댓글이 없습니다.

댓글 쓰기