1865: 웜홀

ewillwin·2023년 7월 18일
0

Problem Solving (BOJ)

목록 보기
132/230

풀이 시간

  • 42m
  • bellman-ford 알고리즘에 대해 공부한 후 풂

구현 방식

  • bellman-ford 알고리즘
    -> 음수 가중치가 있는 그래프의 시작 정점에서 다른 정점들까지의 최단 거리를 구할 수 있음
    -> 음의 사이클의 존재 여부를 알 수 있음
  • "한 지점에서 출발을 하여서 시간여행을 하기 시작하여 다시 출발을 하였던 위치로 돌아왔을 때, 출발을 하였을 때보다 시간이 되돌아가 있는 경우가 있는 지 없는 지" -> bellman-ford 알고리즘을 통해 음의 사이클의 존재여부를 확인하면 된다

코드

import sys


def bellman_ford(graph, start):
    dist = dict()
    for node in graph:
        dist[node] = int(1e9)
    dist[start] = 0

    for i in range(N):
        for node in graph:
            for element in graph[node]:
                nnode, cost = element
                if dist[nnode] > dist[node] + cost:
                    dist[nnode] = dist[node] + cost
                    if i == N-1:
                        return True
    return False


TC = int(sys.stdin.readline()[:-1])
for _ in range(TC):
    N, M, W = map(int, sys.stdin.readline()[:-1].split())
    graph = dict()
    for m in range(M):
        S, E, T = map(int, sys.stdin.readline()[:-1].split())
        if S in graph: graph[S].append((E, T))
        else: graph[S] = [(E, T)]
        if E in graph: graph[E].append((S, T))
        else: graph[E] = [(S, T)]

    for w in range(W):
        S, E, T = map(int, sys.stdin.readline()[:-1].split())
        if S in graph: graph[S].append((E, -T))
        else: graph[S] = [(E, -T)]


    possible = bellman_ford(graph, 1)
    if possible: print("YES")
    else: print("NO")

결과

  • 처음에는 모든 노드에 대해 최단거리를 구하면서 하나의 노드(i)마다 distance[i]가 음수인 경우가 있다면 "YES"를 출력해주는 방식으로 진행하였으나, 시간초과가 발생했다
  • 이 문제는 아무 노드에서부터 bellman-ford를 시행하여 음의 사이클의 존재여부만 확인해주면 되는 문제였다 (초반에 조금 헷갈렸던 게 음의 사이클이 없으나 시간이 역행하는 정점이 없다면 "NO"를 출력해야하는 게 아닌가? 하는 의문이 들었다. 근데 문제 조건에 W는 1 이상이기 때문에 그런 경우는 생각할 필요가 없다~)
profile
Software Engineer @ LG Electronics

2개의 댓글

comment-user-thumbnail
2023년 7월 18일

글 잘 봤습니다, 감사합니다.

답글 달기
comment-user-thumbnail
2023년 7월 18일

아주 유용한 정보네요!

답글 달기