λ°˜μ‘ν˜•
Notice
Recent Posts
Recent Comments
Link
Β«   2025/03   Β»
일 μ›” ν™” 수 λͺ© 금 ν† 
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Archives
Today
Total
03-11 05:31
관리 메뉴

ImJay

[BOJ/Java] 11657. νƒ€μž„λ¨Έμ‹  λ³Έλ¬Έ

μ•Œκ³ λ¦¬μ¦˜/BOJ - Java

[BOJ/Java] 11657. νƒ€μž„λ¨Έμ‹ 

ImJay 2025. 3. 10. 10:10
λ°˜μ‘ν˜•

πŸ“Œ [BOJ/Java] 11657. νƒ€μž„λ¨Έμ‹ 


πŸ’‘ 문제 해석

ν•œ λ„μ‹œμ—μ„œ λ‹€λ₯Έ λ„μ‹œλ‘œ μ΄λ™ν•˜λŠ” λ²„μŠ€ 노선이 주어진닀.
일뢀 λ…Έμ„ μ—λŠ” 음의 κ°€μ€‘μΉ˜(μ‹œκ°„)κ°€ μ‘΄μž¬ν•˜λ©°, 음수 사이클이 λ°œμƒν•  μˆ˜λ„ μžˆλ‹€.

πŸ”Ή 주어진 정보

  • N: λ„μ‹œμ˜ 개수 (λ…Έλ“œ)
  • M: λ²„μŠ€ λ…Έμ„ μ˜ 개수 (κ°„μ„ )
  • A B C: A번 λ„μ‹œμ—μ„œ B번 λ„μ‹œλ‘œ κ°€λŠ” μ‹œκ°„μ΄ C(μ–‘μˆ˜ λ˜λŠ” 음수)

βœ… λͺ©ν‘œ:
1️⃣ 1번 λ„μ‹œμ—μ„œ λͺ¨λ“  λ„μ‹œλ‘œ κ°€λŠ” μ΅œλ‹¨ μ‹œκ°„μ„ κ΅¬ν•œλ‹€.
2️⃣ 음수 사이클이 μ‘΄μž¬ν•˜λŠ”μ§€ νŒλ³„ν•œλ‹€.

3 4
1 2 4
1 3 3
2 3 -1
3 1 -2

πŸš€ 1 → 2 → 3 → 1둜 λŒμ•„μ˜€λ©΄ 음수 사이클 λ°œμƒ!


πŸ“ 풀이 κ³Όμ •

1️⃣ 벨만-ν¬λ“œ (Bellman-Ford) μ•Œκ³ λ¦¬μ¦˜ μ‚¬μš©

βœ” 음수 κ°€μ€‘μΉ˜κ°€ μ‘΄μž¬ν•  수 있기 λ•Œλ¬Έμ— λ‹€μ΅μŠ€νŠΈλΌκ°€ μ•„λ‹Œ 벨만-ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©
βœ” N-1번 λͺ¨λ“  간선을 ν™•μΈν•˜λ©° μ΅œλ‹¨ 경둜 κ°±μ‹ 
βœ” N번째 κ°±μ‹ μ—μ„œ 값이 쀄어듀면 음수 사이클 쑴재!

2️⃣ μ•Œκ³ λ¦¬μ¦˜ 진행 방식

βœ… λͺ¨λ“  μ΅œλ‹¨ 경둜λ₯Ό **λ¬΄ν•œλŒ€(INF)**둜 μ΄ˆκΈ°ν™”
βœ… N-1번 λ™μ•ˆ λͺ¨λ“  간선을 μˆœνšŒν•˜λ©΄μ„œ 거리 κ°±μ‹ 
βœ… N번째 λ°˜λ³΅μ—μ„œ 갱신이 λ°œμƒν•˜λ©΄ 음수 사이클 쑴재!


πŸ’» μ½”λ“œ (Java)

 
import java.util.*;

public class Main {
    static final long INF = Long.MAX_VALUE;
    static int N, M;
    static List<Edge> edges;
    static long[] dist;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        M = sc.nextInt();

        edges = new ArrayList<>();
        dist = new long[N + 1];
        Arrays.fill(dist, INF);
        dist[1] = 0; // μ‹œμž‘μ  μ„€μ •

        for (int i = 0; i < M; i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            int w = sc.nextInt();
            edges.add(new Edge(u, v, w));
        }

        if (bellmanFord()) {
            System.out.println("-1"); // 음수 사이클 쑴재
        } else {
            for (int i = 2; i <= N; i++) {
                System.out.println(dist[i] == INF ? "-1" : dist[i]);
            }
        }
    }

    static boolean bellmanFord() {
        boolean updated = false;
        
        for (int i = 1; i < N; i++) { // N-1번 반볡
            updated = false;
            for (Edge edge : edges) {
                if (dist[edge.u] != INF && dist[edge.v] > dist[edge.u] + edge.w) {
                    dist[edge.v] = dist[edge.u] + edge.w;
                    updated = true;
                }
            }
            if (!updated) break;
        }

        // N번째 λ°˜λ³΅μ—μ„œ κ°±μ‹  λ°œμƒν•˜λ©΄ 음수 사이클 쑴재
        for (Edge edge : edges) {
            if (dist[edge.u] != INF && dist[edge.v] > dist[edge.u] + edge.w) {
                return true;
            }
        }
        return false;
    }

    static class Edge {
        int u, v, w;
        public Edge(int u, int v, int w) {
            this.u = u;
            this.v = v;
            this.w = w;
        }
    }
}

⏱ μ‹œκ°„ λ³΅μž‘λ„ 뢄석

  • 벨만-ν¬λ“œ μ•Œκ³ λ¦¬μ¦˜: O(N × M)
  • N ≤ 500, M ≤ 6000μ΄λ―€λ‘œ μ΅œμ•…μ˜ 경우 500 × 6000 = 3,000,000 μ—°μ‚° (κ°€λŠ₯)

🧐 λŠλ‚€ 점

🌟 벨만-ν¬λ“œλ₯Ό ν™œμš©ν•œ λŒ€ν‘œμ μΈ λ¬Έμ œμ˜€λ‹€.
➑️ 음수 κ°€μ€‘μΉ˜κ°€ ν¬ν•¨λœ κ²½μš°λŠ” λ‹€μ΅μŠ€νŠΈλΌ λŒ€μ‹  벨만-ν¬λ“œ μ‚¬μš©!
➑️ N번째 κ°±μ‹  μ—¬λΆ€λ₯Ό μ²΄ν¬ν•˜λ©΄ 음수 사이클 νŒλ³„μ΄ κ°€λŠ₯ν•˜λ‹€.

πŸ” λ””ν…ŒμΌν•œ λΆ€λΆ„μ—μ„œ μ‹€μˆ˜ν•˜κΈ° 쉬웠닀.
βœ… dist 배열을 Long νƒ€μž…μœΌλ‘œ μ„ μ–Έν•΄μ•Ό μ˜€λ²„ν”Œλ‘œμš° 방지 κ°€λŠ₯!
βœ… μ‹œμž‘μ (1번 λ„μ‹œ)을 0으둜 μ΄ˆκΈ°ν™”ν•˜λŠ” 것 μžŠμ§€ μ•ŠκΈ°
βœ… 음수 사이클이 μ‘΄μž¬ν•˜λ©΄ -1을 λ°”λ‘œ 좜λ ₯ν•˜κ³  μ’…λ£Œν•΄μ•Ό ν•œλ‹€.

πŸš€ 음수 κ°€μ€‘μΉ˜ κ·Έλž˜ν”„ 문제λ₯Ό μ—°μŠ΅ν•˜λŠ” 데 μ•„μ£Ό 쒋은 λ¬Έμ œμ˜€λ‹€! 😊

λ°˜μ‘ν˜•
Comments