ν”Œλ‘œμ΄λ“œ-μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜ Floyd-Warshall Algorithm

이 κΈ€μ˜ λͺ©μ°¨5개
  1. πŸ”Ž ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜μ΄λž€?
  2. βœ… λ‹€μ΅μŠ€νŠΈλΌ vs ν”Œλ‘œμ΄λ“œ μ›Œμ…œ 비ꡐ
  3. 🧐 핡심 κ°œλ…
  4. πŸ“Œ κ΅¬ν˜„ μ˜ˆμ‹œ :
  5. μ½”λ“œ κ΅¬ν˜„ (Java)

πŸš€ ν”Œλ‘œμ΄λ“œ-μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜ Floyd-Warshall Algorithm

λͺ¨λ“  λ…Έλ“œ κ°„ μ΅œλ‹¨ 거리λ₯Ό κ΅¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ, 동적 κ³„νšλ²• (DP)을 ν™œμš©ν•˜μ—¬ 졜적의 경둜λ₯Ό μ°ΎλŠ”λ‹€.

πŸ”Ž ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜μ΄λž€?

**DP(동적 κ³„νšλ²•)**을 μ΄μš©ν•˜μ—¬ λͺ¨λ“  λ…Έλ“œ κ°„μ˜ μ΅œμ†Œ 거리λ₯Ό κ΅¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜ 2차원 배열을 μ‚¬μš©ν•˜μ—¬ 각 λ…Έλ“œ κ°„μ˜ 이동 거리λ₯Ό μ €μž₯ νŠΉμ • λ…Έλ“œλ₯Ό κ²½μœ ν•  λ•Œ, 더 짧은 κ²½λ‘œκ°€ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•˜μ—¬ 거리 정보λ₯Ό κ°±μ‹ 

βœ… λ‹€μ΅μŠ€νŠΈλΌ vs ν”Œλ‘œμ΄λ“œ μ›Œμ…œ 비ꡐ

- ν”Œλ‘œμ΄λ“œ μ›Œμ…œμ€ κ·Έλž˜ν”„ μ „μ²΄μ˜ μ΅œλ‹¨ 경둜λ₯Ό ꡬ할 λ•Œ μ‚¬μš©

- λ…Έλ“œ μˆ˜κ°€ 적고(100 μ΄ν•˜), λͺ¨λ“  경둜λ₯Ό κ³ λ €ν•΄μ•Ό ν•  λ•Œ 적합

🧐 핡심 κ°œλ…

  • λͺ¨λ“  λ…Έλ“œ κ°„μ˜ 거리 정보λ₯Ό μ €μž₯ν•  2차원 λ°°μ—΄ 생성

  • 자기 μžμ‹  β†’ 자기 μžμ‹  거리 = 0

  • μ—°κ²°λ˜μ§€ μ•Šμ€ λ…Έλ“œμ˜ 거리 = λ¬΄ν•œλŒ€ (Integer.MAX_VALUE)

  • 각 κ°„μ„  정보λ₯Ό μž…λ ₯λ°›μ•„ 거리 μ΄ˆκΈ°ν™”

  • λͺ¨λ“  λ…Έλ“œ(i)λ₯Ό β€œκ²½μœ β€ν•˜λ©΄μ„œ μ΅œλ‹¨ 거리 κ°±μ‹ 

  • (좜발 β†’ 도착) vs (좜발 β†’ 경유 β†’ 도착)

  • 더 짧은 거리둜 κ°±μ‹ ν•  수 μžˆλ‹€λ©΄ κ°’ μ—…λ°μ΄νŠΈ

πŸ“Œ κ΅¬ν˜„ μ˜ˆμ‹œ :

μœ„ κ·Έλž˜ν”„λ₯Ό ν† λŒ€λ‘œ 2차원 배열을 λ§Œλ“€λ©΄ λ‹€μŒκ³Ό κ°™λ‹€

μŠ€μŠ€λ‘œμ— λŒ€ν•œ κ±°λ¦¬λŠ” 0으둜 μ·¨κΈ‰ν•˜λ©°, 이어지지 μ•Šμ€ λ…Έλ“œμ— λŒ€ν•΄μ„œλŠ” 거리λ₯Ό λ¬΄ν•œμœΌλ‘œ μ„€μ •ν•œλ‹€.

3쀑 λ°˜λ³΅λ¬Έμ„ μ΄μš©ν•΄μ„œ 2차원 배열을 κ°±μ‹ ν•œλ‹€.

핡심 μ½”λ“œλŠ” λ‹€μŒκ³Ό 같은데, μ΅œμƒμœ„ for문은 1번 λΆ€ν„° 5번 λ…Έλ“œλ₯Ό κ²½μœ ν•  λ•Œλ₯Ό κ°€μ •ν•œλ‹€.

λ‹€μŒμœΌλ‘œ μΆœλ°œλ…Έλ“œ, λ„μ°©λ…Έλ“œλ₯Ό ν™•μΈν•˜μ—¬

1. μΆœλ°œλ…Έλ“œ -> λ„μ°©λ…Έλ“œ

2. μΆœλ°œλ…Έλ“œ -> κ²½μœ λ…Έλ“œ -> λ„μ°©λ…Έλ“œ

2κ°€μ§€ 경우λ₯Ό λΉ„κ΅ν•˜μ—¬ 이동거리가 더 μž‘μ€ κ²ƒμœΌλ‘œ ν•΄λ‹Ή 인덱슀λ₯Ό κ°±μ‹ ν•œλ‹€.

이 λ•Œ, μΆœλ°œλ…Έλ“œ, λ„μ°©λ…Έλ“œ, 경유 λ…Έλ“œκ°€ λ¬΄ν•œ(Integer.MAX_VALUE)인 경우 이동할 수 μ—†λŠ” μƒνƒœμ΄λ―€λ‘œ continueν•˜μ—¬ λ‹€μŒ 경우λ₯Ό ν™•μΈν•œλ‹€.

μ½”λ“œ κ΅¬ν˜„ (Java)

import java.util.*;

class Solution {
    public void solution(int n, int[][] edges) {
        // 1. 2차원 λ°°μ—΄ 생성 및 μ΄ˆκΈ°ν™”
        int[][] floyd = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            Arrays.fill(floyd[i], Integer.MAX_VALUE);
        }

        // 2. 자기 μžμ‹ μœΌλ‘œ κ°€λŠ” κ±°λ¦¬λŠ” 0
        for (int i = 1; i <= n; i++) {
            floyd[i][i] = 0;
        }

        // 3. κ°„μ„  정보 μž…λ ₯ (거리 μ΄ˆκΈ°ν™”)
        for (int[] edge : edges) {
            floyd[edge[0]][edge[1]] = edge[2];
        }

        // 4. ν”Œλ‘œμ΄λ“œ μ›Œμ…œ μ•Œκ³ λ¦¬μ¦˜ μ‹€ν–‰
        for (int k = 1; k <= n; k++) { // 경유 λ…Έλ“œ
            for (int i = 1; i <= n; i++) { // 좜발 λ…Έλ“œ
                for (int j = 1; j <= n; j++) { // 도착 λ…Έλ“œ
                    // κ²½μœ ν•  수 μ—†λŠ” 경우 패슀
                    if (floyd[i][k] == Integer.MAX_VALUE || floyd[k][j] == Integer.MAX_VALUE) {
                        continue;
                    }
                    // μ΅œλ‹¨ 거리 κ°±μ‹ 
                    floyd[i][j] = Math.min(floyd[i][j], floyd[i][k] + floyd[k][j]);
                }
            }
        }

        // 5. κ²°κ³Ό 좜λ ₯ (μ΅œλ‹¨ 거리 ν–‰λ ¬)
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                System.out.print(floyd[i][j] + " ");
            }
            System.out.println();
        }
    }
}
전체 κΈ€ 보기