๋ชจ๋“  ์Œ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ(Floyd-Warshall) ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ์ •์ ์—์„œ ๋‹ค๋ฅธ ์ •์ ์œผ๋กœ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
  • ๊ฐ€์ค‘์น˜(์–‘์˜ ๊ฐ€์ค‘์น˜, ์Œ์˜ ๊ฐ€์ค‘์น˜)๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๋ฐฉํ–ฅ์ด ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ ๊ฒฝ๋กœ ์ฐพ๊ธฐ
  • ๋ชจ๋“  ์ •์ ์— ๋Œ€ํ•ด ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜์—ฌ ํ’€ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ํ”Œ๋กœ์ด๋“œ ์›Œ์ƒฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ DP๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ๋”์šฑ ์‰ฝ๊ณ  ํšจ์œจ์ ์ด๊ฒŒ ํ•ด๊ฒฐํ•œ๋‹ค.

ํ”Œ๋กœ์ด๋“œ ์›Œ์…œ(Floyd-Warshall) ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ์ •์  i์—์„œ ์ •์  j๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” i์—์„œ j๋กœ์˜ ์ง์ ‘ ๋น„์šฉ๊ณผ, i์™€ j๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์ •์ ์„ ๊ฑฐ์น˜๋Š” ๊ฐ„์ ‘ ๋น„์šฉ์„ ๋น„๊ตํ•˜์—ฌ ๋น„์šฉ์ด ๋” ์ ์€ ๊ฐ’์ด ๋œ๋‹ค.
  • ์ด๋•Œ, ๋ชจ๋“  ์Œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฒฝ์œ ์ง€์ธ ์ •์  k๋กœ ์ •์  i์—์„œ ์ •์  j๊นŒ์ง€ ๋ชจ๋“  ์ •์ ์„ ๋Œ€์ž…ํ•ด๋ณด์•„์•ผ ํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ •์  i์—์„œ ์ •์  j๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ๋Š” ๋ชจ๋“  ์ •์ ์„ ๊ฒฝ์œ ์ง€๋กœ ๊ฐ–๋Š” ๋ถ€๋ถ„๋ฌธ์ œ๋“ค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
  • O(N^3)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ

๋กœ์ง

๋กœ์ง ๐Ÿ’ก

  • Di(k)j = ์ •์  {1, 2, โ€ฆ, k}๋งŒ์„ ๊ฒฝ์œ  ๊ฐ€๋Šฅํ•œ ์ •์ ๋“ค๋กœ ๊ณ ๋ คํ•˜๋Š”, ์ •์  i์—์„œ ์ •์  j๊นŒ์ง€์˜ ๋ชจ๋“  ๊ฒฝ๋กœ ์ค‘ ๊ฐ€์žฅ ์งง์€ ๊ฒฝ๋กœ์˜ ๊ฑฐ๋ฆฌ
  • Di(1)j๋Š” ์ •์  i์—์„œ ์ •์  1์„ ๊ฒฝ์œ ํ•˜์—ฌ ์ •์  j๊นŒ์ง€ ๊ฐ€๋Š” ๊ฒฝ๋กœ์™€, ์ •์  i์—์„œ ์ •์  j๋กœ ์ง์ ‘ ๊ฐ€๋Šฅ ๊ฒฝ๋กœ ์ค‘ ์งง์€ ๊ฑฐ๋ฆฌ
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Di(2)j๋Š” ์ •์  i์—์„œ ์ •์  2์„ ๊ฒฝ์œ ํ•˜์—ฌ ์ •์  j๊นŒ์ง€ ๊ฐ€๋Š” ๊ฒฝ๋กœ์™€, Di(1)j ์ค‘ ์งง์€ ๊ฑฐ๋ฆฌ. ์ด๋•Œ, ๊ฒฝ์œ  ๊ฒฝ๋กœ๋Š” Di(1)2 + D2(1)j๊ฐ€ ๋˜๋ฉด์„œ ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ๊ฐ–๊ฒŒ ๋จ.
  • ๊ฒฐ๊ตญ Dikj๋Š” ์ •์  i์—์„œ ์ •์  k๋ฅผ ๊ฒฝ์œ ํ•˜์—ฌ ์ •์  j๊นŒ์ง€ ๊ฐ€๋Š” ๊ฒฝ๋กœ์™€, Di(k-1)j ์ค‘ ์งง์€ ๊ฑฐ๋ฆฌ. ์ด๋•Œ, ๊ฒฝ์œ  ๊ฒฝ๋กœ๋Š” Di(k-1)k + Dk(k-1)j๊ฐ€ ๋˜๋ฉด์„œ ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ๊ฐ–๊ฒŒ ๋จ.

๊ตฌํ˜„

Java
public class FloydWarshallTest {
    static final int INF = 99999;      // ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ๋กœ์˜ ๊ฐ€์ค‘์น˜(์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก Integer.MAX_VALUE ์„ค์ •ํ•˜์ง€ ์•Š์Œ)
    static int N;
    static int[][] dp;

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

        // ๊ฒฝ๋กœ ๋น„์šฉ ์ดˆ๊ธฐํ™”
        for (int i=0; i<N; i++) {
            for (int j=0; j<N; j++) {
                dp[i][j] = sc.nextInt();
                if (i != j && dp[i][j] == 0) dp[i][j] = INF;    // ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ๋กœ๋Š” ๋น„์šฉ์„ ์ตœ๋Œ€๋กœ ์ดˆ๊ธฐํ™”
            }
        }

        positiveFloydWarshall();        // ์–‘์˜ ๊ฐ€์ค‘์น˜ ์ตœ๋‹จ ๊ฒฝ๋กœ
        negativeFloydWarshall();        // ์Œ์˜ ๊ฐ€์ค‘์น˜ ์ตœ๋‹จ ๊ฒฝ๋กœ

    }

    // ์–‘์˜ ๊ฐ€์ค‘์น˜ ์ตœ๋‹จ ๊ฒฝ๋กœ
    public static void positiveFloydWarshall() {
        for (int k=0; k<N; k++) {
            for (int i=0; i<N; i++) {
                if (i == k) continue;                    // ๊ฒฝ์œ ์ง€ = ์ถœ๋ฐœ์ง€์ธ ๊ฒฝ์šฐ pass
                for (int j=0; j<N; j++) {
                    // if (i == j || i == j) continue;   // ๊ฒฝ์œ ์ง€ = ๋„์ฐฉ์ง€์ธ ๊ฒฝ์šฐ, ์ถœ๋ฐœ์ง€ = ๋„์ฐฉ์ง€์ธ ๊ฒฝ์šฐ pass. ํ•˜์ง€๋งŒ ์–ด์ฐจํ”ผ ์ž๊ธฐ์ž์‹ ์œผ๋กœ์˜ ์ด๋™์€ ๋น„์šฉ์ด 0์ด๋ฏ€๋กœ ์ƒ๋žต ๊ฐ€๋Šฅ
                    dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }   
    }

    // ์Œ์˜ ๊ฐ€์ค‘์น˜ ์ตœ๋‹จ ๊ฒฝ๋กœ
    public static void negativeFloydWarshall() {
        for (int k=0; k<N; k++) {
            for (int i=0; i<N; i++) {
                if (i == k) continue;                          // ๊ฒฝ์œ ์ง€ = ์ถœ๋ฐœ์ง€์ธ ๊ฒฝ์šฐ pass
                for (int j=0; j<N; j++) {
                    if (i == j) continue;                      // ์ถœ๋ฐœ์ง€ = ๋„์ฐฉ์ง€์ธ ๊ฒฝ์šฐ
                    if (dp[i][k] != INF && dp[k][j] != INF)    // ์Œ์˜ ๊ฐ€์ค‘์น˜๋Š” ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ๋กœ์˜ ๋น„์šฉ๋„ ๊ฐ์†Œ์‹œ์ผœ ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์• ์ดˆ์— ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ณณ์€ pass
                        dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }
    }
}