λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm

[Algorithm/Java][λ°±μ€€] 1865 μ›œν™€

λ°˜μ‘ν˜•

[BOJ] 1865 μ›œν™€

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

문제 μ ‘κ·Ό

벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ€ λ‹€μŒκ³Ό κ°™λ‹€.
1.μ‹œμž‘ λ…Έλ“œλ₯Ό μ„€μ •ν•œλ‹€.
2.μ΅œλ‹¨ 경둜 ν…Œμ΄λΈ”(λ°°μ—΄)을 μ΄ˆκΈ°ν™”ν•œλ‹€.
3.(μ •μ μ˜ 개수-1)λ²ˆλ™μ•ˆ λͺ¨λ“  간선을 νƒμƒ‰ν•˜μ—¬ μ΅œλ‹¨ 경둜 ν…Œμ΄λΈ”μ„ κ°±μ‹ ν•œλ‹€.
μ—¬κΈ°μ„œ 음의 μˆœν™˜μ΄ λ°œμƒν•˜λŠ”μ§€ μ•Œκ³ μ‹Άλ‹€λ©΄ ν•œλ²ˆ 더 λͺ¨λ“  간선에 λŒ€ν•΄μ„œ 탐색을 ν•˜κ³  μ΄λ•Œ, μ΅œλ‹¨ 경둜 ν…Œμ΄λΈ”μ΄ 갱신이 λœλ‹€λ©΄ 음의 μˆœν™˜μ΄ λ°œμƒν•œ 것이닀.
이 λ¬Έμ œλŠ” λͺ¨λ“  λ…Έλ“œλ₯Ό μ‹œμž‘ λ…Έλ“œλ₯Ό μ„€μ •ν•  ν•„μš”κ°€ 없이 음의 μˆœν™˜μ΄ μžˆλŠ”μ§€ μ—†λŠ”μ§€λ§Œ μ²΄ν¬ν•˜λ©΄ λ˜κΈ°λ•Œλ¬Έμ— 1번 λ…Έλ“œμ— λŒ€ν•΄μ„œλ§Œ 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ„ μˆ˜ν–‰ν•˜κ³  μ΄λ•Œ, 음의 μˆœν™˜μ΄ λ°œμƒν•˜λŠ”μ§€ μ•„λ‹Œμ§€λ₯Ό κ²€μ‚¬ν•˜μ˜€λ‹€.

Code

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

public class BOJ1865 {
    static ArrayList<ArrayList<Node>> list;
    static int[] dist;
    static String answer;
    static int n;
    static private final int INF = 987654321;
    static class Node {
        int to;
        int time;
        Node(int to, int time){
            this.to = to;
            this.time = time;
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        int T = Integer.parseInt(br.readLine());
        while(T-- > 0){
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            n = Integer.parseInt(st.nextToken());
            int v = Integer.parseInt(st.nextToken());
            int w = Integer.parseInt(st.nextToken());
            list = new ArrayList<>();
            for(int i =0 ;i<=n; i++){
                list.add(new ArrayList<>());
            }
            //== μž…λ ₯ λ°›κΈ° ==//
            for(int i = 1; i<=v+w; 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 <= v){
                    list.get(s).add(new Node(e,t));
                    list.get(e).add(new Node(s,t));
                } else {
                    list.get(s).add(new Node(e,t*-1));
                }
            }
            //== 벨만 ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜ μˆ˜ν–‰==//
            dist = new int[n+1];
            answer = bellman_ford() ? "YES":"NO";
            sb.append(answer+"\n");
        }
        System.out.print(sb.toString());
    }
    //==벨만-ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜==//
    public static boolean bellman_ford(){
        //λ°°μ—΄ μ΄ˆκΈ°ν™”
        Arrays.fill(dist,INF);
        //μ‹œμž‘ 지점 μ΄ˆκΈ°ν™”
        dist[1] = 0; 
        boolean update = false;
        // n-1λ²ˆκΉŒμ§€
        for(int i =1; i< n; i++){
            update = false;
            //== μ΅œλ‹¨κ±°λ¦¬ μ΄ˆκΈ°ν™”==//
            for(int j =1; j<= n; j++){
                for(Node n: list.get(j)){
                    if(dist[n.to]>dist[j] + n.time){
                        dist[n.to] = dist[j] + n.time;
                        update = true;
                    }
                }
            }
            // 더이상 μ—…λ°μ΄νŠΈκ°€ μ•ˆλ˜λ©΄ break;
            if(!update) break;
        }
        //nλ²ˆκΉŒμ§€ μ΄€λ‹¨κ²½λ‘œ μ—…λ°μ΄νŠΈκ°€ 이루어진닀면
        //음의 사이클이 μ‘΄μž¬ν•˜λŠ”κ²ƒμ΄λΌκ³  νŒλ‹¨ν•œλ‹€.
        if(update) {
            for (int i = 1; i <= n; i++) {
                for (Node n : list.get(i)) {
                    // μ΄λ•Œ 거리가 쀄어든닀면, 음의 μˆœν™˜μ΄ 이루어지고 μžˆλŠ”κ²ƒμ΄λ‹€.
                    if (dist[n.to] > dist[i] + n.time) {
                        return true;
                    }

                }
            }
        }
        return false;
    }
}

μ–΄λ €μ› λ˜ 점 / 배운 점 / λŠλ‚€ 점

17번 μ œμΆœλ§Œμ— μ„±κ³΅ν–ˆλ‹€.. 사싀 λ‹€λ₯Έ λΈ”λ‘œκ·Έλ₯Ό 쑰금 μ°Έμ‘°ν–ˆλ‹€...λ‹€ ν’€κ³ λ‚˜λ‹ˆκΉŒ λ²¨λ§Œν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ΄ 이해가 λ˜μ—ˆλ‹€.
그리고 였λ₯˜κ°€ λ‚¬λ˜ ν¬μΈνŠΈλŠ”
λ‚΄κ°€ λ²¨λ§Œν¬λ“œλ₯Ό 잘 이해 λͺ»ν•œ 것
a -> b둜 κ°€λŠ” 간선이 ν•˜λ‚˜κ°€ 아닐 μˆ˜λ„ μžˆλ‹€λŠ”κ²ƒ
λ„λ‘œλŠ” μ–‘λ°©ν–₯μ΄λΌλŠ” 것
사싀 2λ²ˆμ§Έκ²ƒλ§Œ μ‹ κ²½μ“°λ©΄ λœλ‹€. 3λ²ˆμ§ΈλŠ” λ‚΄κ°€ 문제λ₯Ό λŒ€μΆ© μ½μ—ˆκ³ , 벨만 ν¬λ“œλŠ”...음...
κ³¨λ“œ3μ΄λΌμ„œ μ—­μ‹œ μ–΄λ €μ› λ‹€...

λ°˜μ‘ν˜•