문제해결(PS)/백준(BOJ)

백준 1865 웜홀

곰탱이장 2025. 1. 25. 14:24

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

 

 이 문제는 양방향 도로와 단방향 웜홀(시간이 뒤로감) 이 주어지고 이 때 음의 사이클이 존재하는지 물어보는 문제이다. 음의 사이클이 있는지를 알아내려면 벨만-포드 알고리즘을 쓰는 것이 제격이다. 

 

 벨만 - 포드 알고리즘은 그래프의 노드의 개수만큼 반복하며, 다익스트라 알고리즘처럼 경유하는 경우가 더 짧을 경우 계속해서 갱신하는 방식이다. 얼핏보면 쓸데 없는 계산을 더하는 것처럼 보이지만, 이 알고리즘의 장점은 이미 그래프의 노드의 개수만큼 반복하여 최적의 거리를 구했다고 생각했을때, 한번 더 돌려서 이때 최적경로가 갱신된다면, 음의 사이클이 생긴 것이라는 것을 알아챌 수 있단 점이다. 

 

 필자는 본디 처음엔 거리 리스트를 math.inf로 했으나 이리하면 실수형과 정수형의 계산에서 오차가 생기므로 그냥 적당히 큰 수를 무한대로 하였다.

import sys
input = sys.stdin.readline
INF=int(100000)

def Bellman(N,graph,d):
    d[1]=0

    for check in range(N):
        for now_node in range(1,N+1):
            for next_node,time in graph[now_node]:
                if d[next_node] > d[now_node] + time:
                    d[next_node] = d[now_node]+time
                    if check == N-1:
                        return False
    
    return True

TS = int(input())
for _ in range(TS):
    N,M,W = map(int,input().split())
    graph=[[] for _ in range(N+1)]
    d = [INF]*(N+1)
    for _ in range(M):
        S,E,T = map(int,input().split())
        graph[S].append([E,T])
        graph[E].append([S,T])
    
    for _ in range(W):
        S,E,T = map(int,input().split())
        graph[S].append([E,-T])
    
    if Bellman(N,graph,d):
        print('NO')
    else:
        print('YES')

'문제해결(PS) > 백준(BOJ)' 카테고리의 다른 글

백준 17070 파이프 옮기기 1  (0) 2025.05.20
백준 2206 벽 부수고 이동하기  (0) 2025.01.27
백준 1238 파티  (0) 2025.01.18
백준 11404 플로이드  (0) 2025.01.18
백준 1167 트리의 지름  (0) 2025.01.17