λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
μ•Œκ³ λ¦¬μ¦˜/λ°±μ€€

λ°±μ€€ - [BOJ 1865] μ›œν™€

by 🐳 Laboon 2024. 7. 6.

문제

λ•ŒλŠ” 2020λ…„, λ°±μ€€μ΄λŠ” μ›”λ“œλ‚˜λΌμ˜ ν•œ ꡭ민이닀. μ›”λ“œλ‚˜λΌμ—λŠ” N개의 지점이 있고 N개의 지점 μ‚¬μ΄μ—λŠ” M개의 λ„λ‘œμ™€ W개의 μ›œν™€μ΄ μžˆλ‹€. (단 λ„λ‘œλŠ” λ°©ν–₯이 μ—†μœΌλ©° μ›œν™€μ€ λ°©ν–₯이 μžˆλ‹€.) μ›œν™€μ€ μ‹œμž‘ μœ„μΉ˜μ—μ„œ 도착 μœ„μΉ˜λ‘œ κ°€λŠ” ν•˜λ‚˜μ˜ 경둜인데, νŠΉμ΄ν•˜κ²Œλ„ 도착을 ν•˜κ²Œ 되면 μ‹œμž‘μ„ ν•˜μ˜€μ„ λ•Œλ³΄λ‹€ μ‹œκ°„μ΄ λ’€λ‘œ κ°€κ²Œ λœλ‹€. μ›œν™€ λ‚΄μ—μ„œλŠ” μ‹œκ³„κ°€ 거꾸둜 κ°„λ‹€κ³  μƒκ°ν•˜μ—¬λ„ μ’‹λ‹€.

μ‹œκ°„ 여행을 맀우 μ’‹μ•„ν•˜λŠ” λ°±μ€€μ΄λŠ” ν•œ κ°€μ§€ κΆκΈˆμ¦μ— λΉ μ‘Œλ‹€. ν•œ μ§€μ μ—μ„œ μΆœλ°œμ„ ν•˜μ—¬μ„œ μ‹œκ°„μ—¬ν–‰μ„ ν•˜κΈ° μ‹œμž‘ν•˜μ—¬ λ‹€μ‹œ μΆœλ°œμ„ ν•˜μ˜€λ˜ μœ„μΉ˜λ‘œ λŒμ•„μ™”μ„ λ•Œ, μΆœλ°œμ„ ν•˜μ˜€μ„ λ•Œλ³΄λ‹€ μ‹œκ°„μ΄ λ˜λŒμ•„κ°€ μžˆλŠ” κ²½μš°κ°€ μžˆλŠ”μ§€ μ—†λŠ”μ§€ κΆκΈˆν•΄μ‘Œλ‹€. μ—¬λŸ¬λΆ„μ€ 백쀀이λ₯Ό 도와 이런 일이 κ°€λŠ₯ν•œμ§€ λΆˆκ°€λŠ₯ν•œμ§€ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ—¬λΌ.

μž…λ ₯

첫 번째 μ€„μ—λŠ” ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€μ˜ 개수 TC(1 ≤ TC ≤ 5)κ°€ μ£Όμ–΄μ§„λ‹€. 그리고 두 번째 쀄뢀터 TC개의 ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€κ°€ μ°¨λ‘€λ‘œ μ£Όμ–΄μ§€λŠ”λ° 각 ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€μ˜ 첫 번째 μ€„μ—λŠ” μ§€μ μ˜ 수 N(1 ≤ N ≤ 500), λ„λ‘œμ˜ 개수 M(1 ≤ M ≤ 2500), μ›œν™€μ˜ 개수 W(1 ≤ W ≤ 200)이 μ£Όμ–΄μ§„λ‹€. 그리고 두 번째 쀄뢀터 M+1번째 쀄에 λ„λ‘œμ˜ 정보가 μ£Όμ–΄μ§€λŠ”λ° 각 λ„λ‘œμ˜ μ •λ³΄λŠ” S, E, T μ„Έ μ •μˆ˜λ‘œ μ£Όμ–΄μ§„λ‹€. S와 EλŠ” μ—°κ²°λœ μ§€μ μ˜ 번호, TλŠ” 이 λ„λ‘œλ₯Ό 톡해 μ΄λ™ν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ„ μ˜λ―Έν•œλ‹€. 그리고 M+2번째 쀄뢀터 M+W+1번째 μ€„κΉŒμ§€ μ›œν™€μ˜ 정보가 S, E, T μ„Έ μ •μˆ˜λ‘œ μ£Όμ–΄μ§€λŠ”λ° SλŠ” μ‹œμž‘ 지점, EλŠ” 도착 지점, TλŠ” μ€„μ–΄λ“œλŠ” μ‹œκ°„μ„ μ˜λ―Έν•œλ‹€. TλŠ” 10,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜ λ˜λŠ” 0이닀.

두 지점을 μ—°κ²°ν•˜λŠ” λ„λ‘œκ°€ ν•œ κ°œλ³΄λ‹€ λ§Žμ„ μˆ˜λ„ μžˆλ‹€. μ§€μ μ˜ λ²ˆν˜ΈλŠ” 1λΆ€ν„° NκΉŒμ§€ μžμ—°μˆ˜λ‘œ 쀑볡 없이 맀겨져 μžˆλ‹€.

좜λ ₯

 

TC개의 쀄에 κ±Έμ³μ„œ λ§Œμ•½μ— μ‹œκ°„μ΄ μ€„μ–΄λ“€λ©΄μ„œ 좜발 μœ„μΉ˜λ‘œ λŒμ•„μ˜€λŠ” 것이 κ°€λŠ₯ν•˜λ©΄ YES, λΆˆκ°€λŠ₯ν•˜λ©΄ NOλ₯Ό 좜λ ₯ν•œλ‹€.


 

λΉ¨κ°„ 글을 보면 λ²¨λ§Œν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ΄λΌλŠ” 것을 μ•Œ 수 μžˆλ‹€.

μ™œ ? ν•œ μ§€μ μ—μ„œ λŒμ•„μ˜€λ‹€ - Cycle, μ‹œκ°„μ΄ λ˜λŒμ•„κ°„λ‹€ - 음수

Negative Cycle을 ν˜•μ„±ν•˜λŠ” κ²ƒμœΌλ‘œ λ²¨λ§Œν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ„ λ– μ˜¬λ¦΄ 수 μžˆλ‹€.

 

벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ€ O(VE) μ΄λ―€λ‘œ 500 * 2700 = 1350000, μΆ©λΆ„ν•˜λ‹€.

 

package com.study.algorithm.boj1865;
import java.io.*;
import java.util.*;

class Pair {
    int e;
    int t;

    Pair(int e, int t) {
        this.e = e;
        this.t = t;
    }

}

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static ArrayList<ArrayList<Pair>> STATIONS;
    static int N, M, W;
    static int INF = (int)1e8;

    public static void main(String[] args) throws IOException {
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();

        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
            //inputDebug();
            sb.append(bellmanFord());
        }
        //inputDebug();
        bw.write(sb.toString());
        bw.close();
        br.close();
    }

    private static String bellmanFord() {
        int dist[] = new int[N + 1];
        Arrays.fill(dist, INF);
        dist[1] = 0;

        for (int loop = 0; loop <= N; loop++) {
            for (int i = 1; i <= N; i++) {
                for (Pair path : STATIONS.get(i)) {
                    if (dist[path.e] > dist[i] + path.t) {
                        if (loop == N) {
                            return "YES\n";
                        }
                        dist[path.e] = dist[i] + path.t;
                    }
                }
            }
        }

        return "NO\n";
    }

    private static void input() throws IOException {
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        W = Integer.parseInt(st.nextToken());

        STATIONS = new ArrayList<>();
        for (int i = 0; i <= N; i++) {
            STATIONS.add(new ArrayList<>());
        }

        int cnt = M + W;
        for (int i = 0; i < cnt; i++) {
            st = new StringTokenizer(br.readLine());
            int s = Integer.parseInt(st.nextToken());
            int e = Integer.parseInt(st.nextToken());
            int t = Integer.parseInt(st.nextToken());

            if (i < M) {
                STATIONS.get(s).add(new Pair(e, t));
                STATIONS.get(e).add(new Pair(s, t));
            } else {
                STATIONS.get(s).add(new Pair(e, -t));
            }
        }
    }
/*
    private static void inputDebug() {
            for (int i = 0; i < STATIONS.size(); i++) {
                for (Pair p : STATIONS.get(i)) {
                    System.out.printf("%d -> %d : %d\n", i, p.e, p.t);
                }
            }
    }*/

}

 

포슀트 쀑 λ²¨λ§Œν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ—μ„œ μ„€λͺ…ν•œ λ‚΄μš©μ²˜λŸΌ Nλ²ˆμ§Έμ— μ΅œλ‹¨κ²½λ‘œκ°€ μ—…λ°μ΄νŠΈ λœλ‹€λ©΄ 음수 사이클이 μ‘΄μž¬ν•œλ‹€κ³  μ•Œ 수 μžˆλ‹€λŠ” 것을 μ΄μš©ν•΄μ„œ ν•΄κ²°ν–ˆλ‹€.

 

https://dev-dot.tistory.com/entry/MST-Bellman-Ford-Algorithm

 

[MST] Bellman-Ford Algorithm

μ΅œλ‹¨κ²½λ‘œ μ•Œκ³ λ¦¬μ¦˜package com.study.datastructrue.mst;import java.util.ArrayList;import java.util.Arrays;class Pair { T node; V cost; public Pair(T node, V cost) { this.node = node; this.cost = cost; }}public class BellmanFord { static long[] dist =

dev-dot.tistory.com