[BOJ] ํƒ€์ž„๋จธ์‹  - ๋ฐฑ์ค€ 11657 (JAVA) - ๋ฒจ๋งŒ-ํฌ๋“œ

    ๐Ÿ“Œ ๋ฒจ๋งŒ-ํฌ๋“œ

    ๋ฒจ๋งŒ-ํฌ๋“œ(bellman-ford-moore) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํŠน์ • ์ถœ๋ฐœ ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

    ๋‹ค์ต์ŠคํŠธ๋ผ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์Œ์ˆ˜ ๊ฐ€์ค‘์น˜ ์—์ง€๊ฐ€ ์žˆ์–ด๋„ ์ˆ˜ํ–‰ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ฃผ๋กœ ์ „์ฒด ๊ทธ๋ž˜ํ”„์—์„œ ์Œ์ˆ˜ ์‚ฌ์ดํด ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ๋ฌธ์ œ๋กœ ๋‚˜์˜จ๋‹ค.

     

     

    1. ์—์ง€ ๋ฆฌ์ŠคํŠธ๋กœ ๊ทธ๋ž˜ํ”„๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”

     

    ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฐฐ์—ด์€ ์ถœ๋ฐœ ๋…ธ๋“œ๋Š” 0, ๋‚˜๋จธ์ง€๋Š” ๋ฌดํ•œ๋Œ€๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. (๊ตฌํ˜„ํ•  ๋•Œ๋Š” Integer.MAX_VALUE๋กœ ์ดˆ๊ธฐํ™”)

    Edge ํด๋ž˜์Šค์— ์ถœ๋ฐœ๋…ธ๋“œ, ๋„์ฐฉ๋…ธ๋“œ, ๊ฐ€์ค‘์น˜๋ฅผ ๋‹ด๊ณ  Edge ํด๋ž˜์Šค ๋ฆฌ์ŠคํŠธ ๋˜๋Š” ๋ฐฐ์—ด์„ ๊ตฌํ˜„ํ•œ๋‹ค.  

     

    2. ๋ชจ๋“  ์—์ง€๋ฅผ ํ™•์ธํ•ด ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฐฐ์—ด ์—…๋ฐ์ดํŠธ, (๋…ธ๋“œ ๊ฐœ์ˆ˜ - 1) ๋ฒˆ ๋ฐ˜๋ณต

     
    ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฐฐ์—ด์„ dist[] ๋ผ๊ณ  ํ•˜๋ฉด, dist[์ถœ๋ฐœ๋…ธ๋“œ] ๊ฐ€ ๋ฌดํ•œ๋Œ€๊ฐ€ ์•„๋‹ˆ๋ฉฐ, dist[๋„์ฐฉ๋…ธ๋“œ] > dist[์ถœ๋ฐœ๋…ธ๋“œ] + ํ•ด๋‹น ์ถœ๋ฐœ-๋„์ฐฉ ๋…ธ๋“œ ๊ฐ€์ค‘์น˜ ์ผ ๋•Œ dist[๋„์ฐฉ๋…ธ๋“œ] ๋ฅผ ๋ถ€๋“ฑํ˜ธ ์˜ค๋ฅธ์ชฝ๊ณผ ๊ฐ™์ด ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค. 

     

    dist[edge.start] != Integer.MAX_VALUE && dis[edge.end] > dist[edge.start] + edge.value

     

    i ๋ฒˆ ๋ฐ˜๋ณตํ–ˆ์„ ๋•Œ์˜ ์ •๋‹ต ๋ฐฐ์—ด์˜ ์˜๋ฏธ๋Š” ์—์ง€๋ฅผ i๋ฒˆ ์ดํ•˜๋กœ ์‚ฌ์šฉํ•ด์„œ ์ถœ๋ฐœ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋…ธ๋“œ๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋‹จ๊ฑฐ๋ฆฌ์ด๋‹ค.

     

    ์Œ์ˆ˜ ์‚ฌ์ดํด์ด ์—†์„ ๋•Œ ํŠน์ • ๋…ธ๋“œ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์—์ง€์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๊ฐ€ (๋…ธ๋“œ ๊ฐœ์ˆ˜ - 1)์ด๊ธฐ ๋•Œ๋ฌธ์—  (๋…ธ๋“œ ๊ฐœ์ˆ˜ - 1)๋งŒํผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

     

    ์Œ์ˆ˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด (๋…ธ๋“œ ๊ฐœ์ˆ˜ - 1) ๋ฒˆ ๋ฐ˜๋ณต ํ›„์—๋Š” ์ถœ๋ฐœ ๋…ธ๋“œ์™€ ๋‹ค๋ฅธ ๋…ธ๋“œ ๊ฐ„์— ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    ๋งŒ์•ฝ ์Œ์ˆ˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค๋ฉด ํ•œ ๋ฒˆ ๋” ๋ฐ˜๋ณตํ–ˆ์„ ๋•Œ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๊ฐ’์ด ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— ์—…๋ฐ์ดํŠธ ์—ฌ๋ถ€๋กœ ์Œ์ˆ˜ ์‚ฌ์ดํด ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๐Ÿ”’ ํƒ€์ž„๋จธ์‹  - ๋ฐฑ์ค€ 11657

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

     

    ๋ฌธ์ œ

    N๊ฐœ์˜ ๋„์‹œ๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•œ ๋„์‹œ์—์„œ ์ถœ๋ฐœํ•˜์—ฌ ๋‹ค๋ฅธ ๋„์‹œ์— ๋„์ฐฉํ•˜๋Š” ๋ฒ„์Šค๊ฐ€ M๊ฐœ ์žˆ๋‹ค. ๊ฐ ๋ฒ„์Šค๋Š” A, B, C๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š”๋ฐ, A๋Š” ์‹œ์ž‘๋„์‹œ, B๋Š” ๋„์ฐฉ๋„์‹œ, C๋Š” ๋ฒ„์Šค๋ฅผ ํƒ€๊ณ  ์ด๋™ํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด๋‹ค. ์‹œ๊ฐ„ C๊ฐ€ ์–‘์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. C = 0์ธ ๊ฒฝ์šฐ๋Š” ์ˆœ๊ฐ„ ์ด๋™์„ ํ•˜๋Š” ๊ฒฝ์šฐ, C < 0์ธ ๊ฒฝ์šฐ๋Š” ํƒ€์ž„๋จธ์‹ ์œผ๋กœ ์‹œ๊ฐ„์„ ๋˜๋Œ์•„๊ฐ€๋Š” ๊ฒฝ์šฐ์ด๋‹ค.

    1๋ฒˆ ๋„์‹œ์—์„œ ์ถœ๋ฐœํ•ด์„œ ๋‚˜๋จธ์ง€ ๋„์‹œ๋กœ ๊ฐ€๋Š” ๊ฐ€์žฅ ๋น ๋ฅธ ์‹œ๊ฐ„์„ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

     

    ์ž…๋ ฅ

    ์ฒซ์งธ ์ค„์— ๋„์‹œ์˜ ๊ฐœ์ˆ˜ N (1 ≤ N ≤ 500), ๋ฒ„์Šค ๋…ธ์„ ์˜ ๊ฐœ์ˆ˜ M (1 ≤ M ≤ 6,000)์ด ์ฃผ์–ด์ง„๋‹ค. ๋‘˜์งธ ์ค„๋ถ€ํ„ฐ M๊ฐœ์˜ ์ค„์—๋Š” ๋ฒ„์Šค ๋…ธ์„ ์˜ ์ •๋ณด A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. 

     

    ์ถœ๋ ฅ

    ๋งŒ์•ฝ 1๋ฒˆ ๋„์‹œ์—์„œ ์ถœ๋ฐœํ•ด ์–ด๋–ค ๋„์‹œ๋กœ ๊ฐ€๋Š” ๊ณผ์ •์—์„œ ์‹œ๊ฐ„์„ ๋ฌดํ•œํžˆ ์˜ค๋ž˜ ์ „์œผ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ฒซ์งธ ์ค„์— -1์„ ์ถœ๋ ฅํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด N-1๊ฐœ ์ค„์— ๊ฑธ์ณ ๊ฐ ์ค„์— 1๋ฒˆ ๋„์‹œ์—์„œ ์ถœ๋ฐœํ•ด 2๋ฒˆ ๋„์‹œ, 3๋ฒˆ ๋„์‹œ, ..., N๋ฒˆ ๋„์‹œ๋กœ ๊ฐ€๋Š” ๊ฐ€์žฅ ๋น ๋ฅธ ์‹œ๊ฐ„์„ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅํ•œ๋‹ค. ๋งŒ์•ฝ ํ•ด๋‹น ๋„์‹œ๋กœ ๊ฐ€๋Š” ๊ฒฝ๋กœ๊ฐ€ ์—†๋‹ค๋ฉด ๋Œ€์‹  -1์„ ์ถœ๋ ฅํ•œ๋‹ค.

    ๐Ÿ”‘ ํ•ต์‹ฌ ์•„์ด๋””์–ด

    ๋ฒจ๋งŒ-ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ

    ๐Ÿ”Ž ์ฃผ์˜ํ•  ์ 

    distance ๋ฐฐ์—ด์„ int ๋ฐฐ์—ด๋กœ ์„ ์–ธํ•˜๋ฉด ์ถœ๋ ฅ์ดˆ๊ณผ๋กœ ๋‚˜์˜จ๋‹ค.

     

    ๋ฒจ๋งŒ ํฌ๋“œ๋Š” ์ „์ฒด ๊ณผ์ •์„ ์—์ง€์˜ ์ˆ˜(M)๋งŒํผ ๋Œ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—, ์Œ์ˆ˜ ์‚ฌ์ดํด์˜ ์ ˆ๋Œ“๊ฐ’์˜ ์ตœ๋Œ€ ๊ธธ์ด๊ฐ€ 6์ฒœ๋งŒ(M<=6000, |C|<=10,000)์ด๋ผ๋ฉด ๊ทธ ๊ณผ์ •์„ ๋‹ค์‹œ N๋ฒˆ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ N์„ ๊ณฑํ•œ ๊ฒƒ๋งŒํผ ์ ˆ๋Œ“๊ฐ’์„ ํ‚ค์šฐ๊ฒŒ ๋œ๋‹ค. (N ≤ 500 -> 21์–ต int ๋ฒ”์œ„ ๋„˜์Œ)

    ๋”ฐ๋ผ์„œ distance ๋ฐฐ์—ด์„ long ํƒ€์ž…์œผ๋กœ ํ•ด์•ผ ํ•œ๋‹ค.

     

    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int N = sc.nextInt();
            int M = sc.nextInt();
    
            Edge[] edges = new Edge[M];
    
            for (int i = 0; i < M; i++) {
                int u = sc.nextInt();
                int v = sc.nextInt();
                int w = sc.nextInt();
                edges[i] = new Edge(u,v,w);
            }
    
            long[] distance = new long[N+1];
            for (int i = 0; i <= N; i++) {
                distance[i] = Integer.MAX_VALUE;
            }
    
            // ๋ฒจ๋งŒ-ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
            distance[1] = 0; // 1๋ฒˆ ๋„์‹œ์— ์ถœ๋ฐœ
            for (int i = 1; i < N; i++) { // N-1๋ฒˆ ์—…๋ฐ์ดํŠธ
                for (int j = 0; j < M; j++) { // ๋ชจ๋“  ์—์ง€ ํ™•์ธ
                    Edge edge = edges[j];
                    if(distance[edge.start] != Integer.MAX_VALUE){ // "<" ๋„ ๋งž์Œ
                        if(distance[edge.end] > distance[edge.start]+edge.value){
                            distance[edge.end] = distance[edge.start]+edge.value;
                        }
                    }
                }
            }
            // ์Œ์ˆ˜ ์‚ฌ์ดํด ํ™•์ธ
            boolean isCycle = false;
            for (int i = 0; i < M; i++) { 
                Edge edge = edges[i];
                if(distance[edge.start] != Integer.MAX_VALUE){
                    if(distance[edge.end] > distance[edge.start]+edge.value){
                        isCycle = true;
                    }
                }
            }
            if(!isCycle){
                for (int i = 2; i <=N; i++) {
                    if(distance[i] == Integer.MAX_VALUE) // 1๋ฒˆ์—์„œ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๋…ธ๋“œ
                        System.out.println(-1);
                    else
                        System.out.println(distance[i]);
                }
            }else{
                System.out.println(-1);
            }
        }
    }
    class Edge{
        int start, end, value;
    
        public Edge(int start, int end, int value) {
            this.start = start;
            this.end = end;
            this.value = value;
        }
    }

     

     


    ์ฝ”ํ…Œ ์ •๋ฆฌ ๊นƒํ—ˆ๋ธŒ ๋งํฌ

     

    GitHub - HyperAlgorithmStudy/BaekJoon: Do it! ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ์Šคํ„ฐ๋””

    Do it! ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ์Šคํ„ฐ๋””. Contribute to HyperAlgorithmStudy/BaekJoon development by creating an account on GitHub.

    github.com

    ์ฐธ๊ณ : Do it! ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ: ์ž๋ฐ” ํŽธ - ๊น€์ข…๊ด€

    728x90

    ๋Œ“๊ธ€