둠치킨
코딩하는 둠치킨
둠치킨

블로그 메뉴

  • 홈
  • 분류 전체보기 (231) N
    • 프로그래머스 (3)
      • 해시 (1)
      • 다익스트라 (1)
      • 크루스칼 (1)
    • BOJ (180) N
      • 스택 (14)
      • 큐 (5)
      • 덱 (4)
      • 그래프 (32)
      • 배열 (8)
      • 재귀 (12)
      • 브루트 포스 (2)
      • 그리디 알고리즘 (7)
      • 다이내믹 프로그래밍 (14)
      • 백트래킹 (24)
      • 기하학 (4)
      • 트리 (4)
      • 구현 (14)
      • 수학 (3)
      • 맵 (1)
      • 다익스트라 (2)
      • 누적합 (5)
      • 유니온 파인드 (1)
      • 분할 정복 (2)
      • 벨만-포드 (1)
      • 이분 탐색 (5) N
    • 자료구조 (15)
      • 스택 (3)
      • 큐 (5)
      • 덱 (2)
      • 그래프 (1)
      • 트리 (2)
      • 힙 (1)
      • 정렬 (1)
    • C++ (11)
      • 모두의코드 (2)
      • Effective C++ (3)
      • C++ STL (6)
    • 컴파일러 (1)
    • OS (17)
    • 컴퓨터 구조 (2)
    • Unreal Engine 5 (2)

공지사항

전체 방문자
오늘
어제

인기 글

최근 글

태그

  • BFS
  • boj
  • Bruteforce
  • C
  • C++
  • C++ STL
  • Cache Memory
  • deadlock
  • DFS
  • Effective C++
  • java
  • Mutex
  • next_permutation
  • os
  • Process
  • rotate
  • semaphore
  • spin lock
  • STL
  • STL C++
hELLO · Designed By 정상우.
둠치킨

코딩하는 둠치킨

BOJ/벨만-포드

1865번: 웜홀

2025. 9. 9. 13:38

1865번: 웜홀

사용 언어: C++

문제 요약

시간 여행을 매우 좋아하는 백준이는 한 가지 궁금증에 빠졌다. 한 지점에서 출발을 하여서 시간여행을 하기 시작하여 다시 출발을 하였던 위치로 돌아왔을 때, 출발을 하였을 때보다 시간이 되돌아가 있는 경우가 있는지 없는지 궁금해졌다. 여러분은 백준이를 도와 이런 일이 가능한지 불가능한지 구하는 프로그램을 작성하여라.

벨만-포드 설명

문제를 읽어보면 간단하게 정리하자면 출발점으로 돌아왔을 때 시간이 역행하는 경로가 있냐 -> 즉, 음수 사이클이 존재하는지 확인하는 문제.

벨만-포드 요약

1. 단일 출발점 최단 거리 계산 알고리즘

2. 음수 간선 포함 가능

3. 음수 사이클 탐지 가능

구현 흐름

1. 거리 배열 초기화

vector<int> dist(N+1, 0); // 모든 노드를 시작점처럼 0으로 초기화

2. 모든 간선에 대해 반복적으로 거리 갱신

struct Edge
{
    int from, to, weight;
}

/* 
N번 반복 이유: 
- 최단 경로는 정점 수 N-1개 이하의 간선만 지나므로
- N-1번 반복 후 거리 배열이 안정화됨
- 이후 반복에서 갱신이 발생하면 음수 사이클이 존재하는 것
*/
for(int i=0; i<N; i++)
{
    for(auto edge : edges)
    {
        if(dist[edge.from] + edge.weight < dist[edge.to])
        {
            dist[edge.to] = dist[edge.from] + edge.weight;
        }
    }
}

3. 음수 사이클 확인

bool hasNegativeCycle = false;
for(auto edge : edges)
{
    // 이미 최단 경로 다 갱신했는데, 또 갱신이 된다? -> 음수 사이클 존재
    if(dist[edge.from] + edge.weight < dist[edge.to])
    {
        hasNegativeCycle = true;
        break;
    }
}

풀이

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct Edge
{
    int from, to, weight;
};

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int TC;
    cin >> TC;
    
    while(TC--)
    {
        int N, M, W;
        cin >> N >> M >> W;
        vector<int> dist(N+1, 0);
        vector<Edge> edges;
        
        int S, E, T;
        for(int i=0; i<M+W; i++)
        {
            cin >> S >> E >> T;
            if(i >= M) T *= -1;
            else edges.push_back({E, S, T});
            edges.push_back({S, E, T});
        }
        
        for(int i=0; i<N; i++)
        {
            for(auto& edge : edges)
            {
                int u = edge.from;
                int v = edge.to;
                int w = edge.weight;
                
                if(dist[u] + w < dist[v]) dist[v] = dist[u] + w;
            }   
        }
        
        bool hasNegativeCycle = false;
        for(auto edge : edges)
        {
            if(dist[edge.from] + edge.weight < dist[edge.to])
            {
                hasNegativeCycle = true;
                break;
            }
        }
        
        hasNegativeCycle ? cout << "YES\n" : cout << "NO\n";
    }

    return 0;
}
저작자표시 (새창열림)
    둠치킨
    둠치킨
    코딩 공부를 위한 코딩 블로그 기록 일기

    티스토리툴바