[백준 알고리즘] 1865번: 웜홀 (Java / 자바)

2025. 4. 23. 10:33·알고리즘/백준

음수사이클이 있는지 판단하는 문제이다.

어려운 점은 특정 지점에서 시작했을 때 사이클이 존재하는지 판단하는게 아니라

전체 그래프에서 음수사이클이 발생하는경우가 있는지 체크해야한다.

1) 모든 지점에서 벨만포드 수행

- 이렇게도 풀 수 있다고 한다.

2) 가상 시작점 만들기

- 나는 이렇게 풀었는데,

안쓰는 0번에서 단방향으로 모든 vertex에 가중치 0으로 연결해줬다.

그리고 나서 벨만포드의 시작점을 0번으로 해서

0->1,2,3,4.... ->0 (사이클발생) -> 1,2,3,4... (갱신 과정에서 사이클 탐지)

이런 방식으로 벨만포드를 한번만 수행하고 풀 수 있었다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

// 특정 지점에서 출발해서 다시 돌아와야함
// 모든 지점에서 dfs 수행? 불가
// 벨만 포드 사용 O(VE) -> O(500*(2700)) -> O(1250000) 한번 수행에 백만정도
// * T(5) 
// 음수 사이클 판별로 풀기

public class boj1865 {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	static int T, N, M, W;
	static final int INF = 1000000000;
	static int[] dist; // 출발지부터의 거리를 기록하는 배열
	static ArrayList<Edge> edges;
	
	static class Edge {
		int v; // 나가는 정점
		int w; // 들어오는 정점
		int cost;
		
		public Edge(int v, int w, int cost) {
			this.v = v;
			this.w=w;
			this.cost=cost;
		}
	}
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		T = Integer.parseInt(br.readLine());
		for (int t=0; t<T; t++) {
			input();
			boolean isCycle = bellmanFord();
			if (isCycle) System.out.println("YES");
			else System.out.println("NO");
		}
	}
	
	static private boolean bellmanFord() {
		dist = new int[N+1];
		Arrays.fill(dist, INF);
		
		dist[0] = 0; // 시작점
		
		for (int i=0; i<=N; i++) {  // 정점 개수만큼 반복
			for (int j=0; j<edges.size(); j++) {  // 간선 개수만큼 반복
				Edge edge = edges.get(j);  // 현재 간선
				
				// 현재 간선에서, 들어오는 정점에 대해 비교
				if (dist[edge.v] != INF && dist[edge.w] > dist[edge.v] + edge.cost) {
					// 갱신 조건: 새롭게 들어오는 정점 v + cost 가 더 효율적 (기존 dist에 저장된 도착점보다)
					dist[edge.w] = dist[edge.v] + edge.cost;
				}
			}
		}
		
		// 음수 사이클 탐지 (위에서 한번 다 돌렸는데 또 갱신되는경우)
		for (int i=0; i<edges.size(); i++) {
			Edge edge = edges.get(i);
			if (dist[edge.v] != INF && dist[edge.w] > dist[edge.v] + edge.cost) {
				return true; // 음수 사이클 있음
			}
		}
		
		return false;
	}
	
	static private void input() throws IOException {
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		W = Integer.parseInt(st.nextToken());
		
		edges = new ArrayList<>();
		
		for (int i=0; i<M; i++) {
			st = new StringTokenizer(br.readLine());
			int v = Integer.parseInt(st.nextToken());
			int w = Integer.parseInt(st.nextToken());
			int c = Integer.parseInt(st.nextToken());
			edges.add(new Edge(v, w, c));
			edges.add(new Edge(w, v, c));
		}
		for (int i=0; i<W; i++) {
			st = new StringTokenizer(br.readLine());
			int v = Integer.parseInt(st.nextToken());
			int w = Integer.parseInt(st.nextToken());
			int c = Integer.parseInt(st.nextToken());
			edges.add(new Edge(v, w, -c));
		}
		
		// 가장 시작점에서 모든 지점 연결
		for (int i=1; i<=N; i++) {
			edges.add(new Edge(0, i, 0));
		}
	}
}
저작자표시 (새창열림)

'알고리즘 > 백준' 카테고리의 다른 글

[백준 알고리즘] 2096번: 내려가기 (Java / 자바)  (0) 2025.04.24
[백준 알고리즘] 11404번: 플로이드 (Java / 자바)  (0) 2025.04.23
[백준 알고리즘] 9095번: 1, 2, 3 더하기 (Python / 파이썬)  (0) 2024.02.28
[백준 알고리즘] 1463번: 1로 만들기 (Python / 파이썬)  (0) 2024.02.28
[백준 알고리즘] 1992번: 쿼드트리 (Python / 파이썬)  (0) 2024.02.19
'알고리즘/백준' 카테고리의 다른 글
  • [백준 알고리즘] 2096번: 내려가기 (Java / 자바)
  • [백준 알고리즘] 11404번: 플로이드 (Java / 자바)
  • [백준 알고리즘] 9095번: 1, 2, 3 더하기 (Python / 파이썬)
  • [백준 알고리즘] 1463번: 1로 만들기 (Python / 파이썬)
gyujh
gyujh
개발 공부 블로그
  • gyujh
    규
    gyujh
  • 전체
    오늘
    어제
    • 분류 전체보기 (86)
      • Backend&DB (3)
      • CS (5)
        • 컴퓨터구조 (1)
        • 소프트웨어공학 (4)
      • JavaScript (2)
      • Git (2)
      • 알고리즘 (73)
        • 개념 (3)
        • 백준 (70)
      • Projects (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    BOJ
    답
    정답
    구현
    풀이
    문자열
    백준
    프로그래머스
    스택
    재귀
    딕셔너리
    정렬
    답안
    시간초과
    알고리즘
    숏코딩
    에러
    algorithm
    너비우선탐색
    런타임
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
gyujh
[백준 알고리즘] 1865번: 웜홀 (Java / 자바)
상단으로

티스토리툴바