๐ค Floyd-Warshall ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ?
๊ทธ๋ํ์ ์๋ ๋ชจ๋ ์ ์ ์ ๋ํด ๊ฐ ์ ์ ๋ค์ด ๋ค๋ฅธ ์ ์ ๋ค๊น์ง ๋๋ฌํ๊ธฐ ์ํด ํ์ํ ๋ชจ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ๋ ์ฌ์ฉํฉ๋๋ค.
ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ฑฐ์ณ๊ฐ๋ ์ ์ ์ ๊ธฐ์ค์ผ๋ก ์๊ณ ๋ฆฌ์ฆ์ ์ํํ๋ ํน์ง์ด ์์ต๋๋ค.
์ฆ, ์ ์ A, ์ ์ B ๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๊ธฐ ์ํด ์ค๊ฐ์์ ๊ฑฐ์ณ๊ฐ ์ ์๋ ๋ชจ๋ ์ ์ ๋ค์ ํ์ธํด๋ณด๊ณ ๊ทธ ์ค ์ต๋จ ๊ฑฐ๋ฆฌ์ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ต๋๋ค.
(ํ๋ก์ด๋ ์์ฌ์ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ ์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ์ด๊ณ , ์ธ์ ํ๋ ฌ๋ก ํํํ์ฌ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํฉ๋๋ค.)
โ ์๊ฐ๋ณต์ก๋
3์ค for๋ฌธ์ ํตํด ๊ฑฐ์ณ๊ฐ๋ ์ ์ ์ ์ด์ฉํ์ฌ ๊ทธ๋ํ๋ฅผ ํ์ํ๊ธฐ ๋๋ฌธ์ O(n^3)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ต๋๋ค.
โ ํ์ ๋ฐฉ๋ฒ
๋ฌธ์ ์ ํจ๊ป ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ ํ์๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋์ด๋ : ๊ณจ๋ ๐ฅ
11404๋ฒ: ํ๋ก์ด๋
์ฒซ์งธ ์ค์ ๋์์ ๊ฐ์ n์ด ์ฃผ์ด์ง๊ณ ๋์งธ ์ค์๋ ๋ฒ์ค์ ๊ฐ์ m์ด ์ฃผ์ด์ง๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์งธ ์ค๋ถํฐ m+2์ค๊น์ง ๋ค์๊ณผ ๊ฐ์ ๋ฒ์ค์ ์ ๋ณด๊ฐ ์ฃผ์ด์ง๋ค. ๋จผ์ ์ฒ์์๋ ๊ทธ ๋ฒ์ค์ ์ถ๋ฐ ๋์์ ๋ฒํธ๊ฐ
www.acmicpc.net
์ ์์ ๋ฅผ ๊ทธ๋ํ๋ก ํํํ๋ฉด ์์ ๊ทธ๋ฆผ์ฒ๋ผ ํํํ ์ ์์ต๋๋ค.
๊ฐ ์ ์ ๋ค์ ๋์์ด๊ณ ํ์ดํ์ ์ซ์๋ ๋์์์ ๋ค๋ฅธ ๋์๋ก ๊ฐ๊ธฐ์ํ ๋น์ฉ์ ๋๋ค.
๋ฌธ์ ๋ ๋ชจ๋ ๋์์ ์์ ๋ํด์ ๋์A์์ B๋ก ๊ฐ๋๋ฐ ํ์ํ ์ต์ ๋น์ฉ์ ๊ตฌํด์ผ ํฉ๋๋ค.
ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋ชจ๋ ์ ์ ์ ๋ํด ๊ฐ ์ ์ ๋ค์ด ๋ค๋ฅธ ์ ์ ๋ค๊น์ง ๋๋ฌํ๊ธฐ ์ํด ํ์ํ ๋ชจ๋ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ๋ ์ฌ์ฉํฉ๋๋ค.
์ฆ, ์ด ๋ฌธ์ ํ์ด์ ์ ์ฉํด๋ณผ ์ ์๊ฒ ์ต๋๋ค.
๊ฐ ์ ์ ์์ ๋ค๋ฅธ ์ ์ ๊น์ง์ ์ต์ ๋น์ฉ์ ์ด์ฐจ์ ๋ฐฐ์ด์ ํํ๋ก ํํํ๋ฉด ์๋์ ๊ฐ์ด ํํํ ์ ์์ต๋๋ค.
( 0์ ์๊ธฐ ์์ (A, A)์ด๊ธฐ ๋๋ฌธ์ ๋น์ฉ์ด 0์ ์ ๋๋ค, X ๋ ์ฐ๊ฒฐ๋์ง ์์ ๊ฐ ์ ์๋ ๋ถ๋ถ์ ๋๋ค )
0 | 2 | 3 | 1 | 10 |
X | 0 | X | 2 | X |
8 | X | 0 | 1 | 1 |
X | X | X | 0 | 3 |
7 | 4 | X | X | 0 |
int n = Integer.parseInt(br.readLine()); // 5 ๋์์ ์
int m = Integer.parseInt(br.readLine()); // 14 ๋์์ ์ฐ๊ฒฐ๋ ๊ฒฝ๋ก์ ์
int x = 100000 * (n-1) + 1;
int[][] city = new int[n + 1][n + 1];
// ์ด๊ธฐ ์ด์ฐจ์ ๋ฐฐ์ด ์ ์ฒด๋ฅผ x์ 0์์ธ ๋ถ๋ถ์ 0์ด ๋๋๋ก ์ธํ
ํด์ค๋๋ค.
for (int i = 1; i < city.length; i++) {
for( int j = 1; j<city[i].length; j++){
city[i][j] = x;
if( i == j ){
city[i][j] = 0;
}
}
}
// ์ต์ ๋น์ฉ์ ๊ตฌํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ์ ์ ๋น์ฉ์ผ๋ก ์ธํ
ํฉ๋๋ค.
// ์ด๋ ๊ฒ๊น์ง ํ๋ฉด ์์ ํ์ฒ๋ผ ์ด์ฐจ์ ๋ฐฐ์ด์ ์ธํ
ํ์์ต๋๋ค.
for( int i = 0; i<m; i++){
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
city[a][b] = Math.min(city[a][b], cost);
}
๐ ์ฐ๊ฒฐ๋์ง ์์ X์ ๊ฐ ์ค์
์ต๋๊ฐ(๋ฌดํ)์ ์๊ฐํด์ Integer.MAX_VALUE๋ฅผ ์ค์ ํด ๋ณด์์ง๋ง ๋ค๋ฅธ ๊ฒฝ๋ก์ ๋น์ฉ๊ณผ ํฉ์ณ์ง๊ฒ ๋๋ฉด ์์๊ฐ ๋์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค ๐ญ
int x = 100000 * ( n - 1 ) + 1
๋น์ฉ(์ฐ๊ฒฐ๋ ๊ฐ์ ์ ๊ฐ์ค์น) ์ ์ต๋๊ฐ * ๊ฐ์ ์ ์(=๋
ธ๋์ ์ - 1 ) ๋ณด๋ค ์ปค์ผํ๊ธฐ ๋๋ฌธ์ + 1
๊ฒฝ๋ก๊ฐ ์๋ ๋ถ๋ถ์ ์ต๋๊ฐ(๋ฌดํ)์ผ๋ก ์ค์ ํ๋ ์ด์ ๋ ์ค์ ๊ฒฝ๋ก๊ฐ ์กด์ฌํ์ง ์์์ ๋ํ๋ด๊ธฐ ์ํจ์
๋๋ค.
์๋ฅผ๋ค์ด 1->2->3->4->5 ์ฒ๋ผ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๊ฑฐ์ณ์ ๋์ฐฉํ ๋น์ฉ์
๋น์ฉ * ๊ฐ์ ์ ์ ๋ก ํํํ ์ ์์ต๋๋ค ํ์ง๋ง ๋ง์ฝ ๊ฒฝ๋ก๊ฐ ์๋ x๊ฐ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๊ฑฐ์น ๋น์ฉ๋ณด๋ค ์๋ค๋ฉด ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ฒฝ๋ก๊ฐ ์๋ x์ ๊ฐ์ผ๋ก ๋น์ฉ์ ์ธํ
ํ๊ฒ๋์ด ์๊ณ ๋ฆฌ์ฆ์ ์ค๋ฅ๋ก ์ด์ด์ง๊ฒ ๋ฉ๋๋ค.
์ธํ ๋ ์ด์ฐจ์ ๋ฐฐ์ด์ ํ๋ก์ด๋-์์ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ต์ ๋น์ฉ์ ํ์ํฉ๋๋ค.
for( int k = 1; k<=n; k++){ // k : ๊ฑฐ์ณ๊ฐ๋ ๋์
for( int i = 1; i<=n; i++){ // i : ๋์A
for( int j = 1; j<=n; j++){ // j : ๋์B
if( i != j){
city[i][j] = Math.min(city[i][j], city[i][k] + city[k][j]);
}
}
}
}
๊ฒฝ๋ก๊ฐ ์์ ๊ฒฝ์ฐ ( ์ : k = 1, i = 3, j = 4 )
city[3][4] 3(i)์์ 4(j)๋ฅผ ๋ฐ๋ก ๊ฐ๋ ๊ฒฝ์ฐ vs city[i][k] + city[k][j] 3(i)์์1(k)์ ๊ฑฐ์ณ 4(j)๋ก ๊ฐ๋ ๊ฒฝ์ฐ๋ฅผ ๋น๊ตํ์ฌ ๋ ์ ์ ๋น์ฉ์ ์ธํ ํฉ๋๋ค. ( 1๋ก ์ธํ )
๊ฒฝ๋ก๊ฐ ์์ ๊ฒฝ์ฐ ( ์ : k = 2, i = 4, j = 5 )
city[i][j] = 3 vs city[i][k] + city[k][j] = X + X
๊ฒฝ๋ก๊ฐ ์์๊ฒฝ์ฐ X๋ฅผ ๋ํ๊ฒ ๋จ์ผ๋ก ๋ฐ๋ก ๊ฐ๋ ๊ฒฝ๋ก๊ฐ ์๋ค๋ฉด ๋น์ฐํ ๊ฑฐ์ณ๊ฐ๋ ๊ฒฝ๋ก๋ณด๋ค ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๊ฐ๋ ๊ฒฝ๋ก๊ฐ ์ธํ ๋์ด์ง๋๋ค ( 3์ผ๋ก ์ธํ )
์ด์ฒ๋ผ ๋ฐ๋ก ๊ฐ๋ ๊ฒฝ๋ก์, ๊ฑฐ์ณ๊ฐ๋ ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ ๋น๊ตํ๋ฉด์ ๊ฐ ์ ์ ๊ณผ์ ์ต์ ๋น์ฉ(๋๋ ์ต๋จ ๊ฑฐ๋ฆฌ)๋ฅผ ์ด์ฐจ์ ๋ฐฐ์ด๋ก ๋ํ๋ผ ์ ์๊ฒ๋ฉ๋๋ค.
๐ ์ ์ฒด ์ฝ๋
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.lang.StringBuilder;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
int n = Integer.parseInt(br.readLine());
int m = Integer.parseInt(br.readLine());
int x = 100000 * (n-1) + 1;
int[][] city = new int[n + 1][n + 1];
for (int i = 1; i < city.length; i++) {
for( int j = 1; j<city[i].length; j++){
city[i][j] = x;
if( i == j){
city[i][j] = 0;
}
}
}
for( int i = 0; i<m; i++){
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int cost = Integer.parseInt(st.nextToken());
city[a][b] = Math.min(city[a][b], cost);
}
for( int k = 1; k<=n; k++){
for( int i = 1; i<=n; i++){
for( int j = 1; j<=n; j++){
if( i != j){
city[i][j] = Math.min(city[i][j], city[i][k] + city[k][j]);
}
}
}
}
for( int i = 1; i<=n; i++){
for (int j = 1; j <= n; j++) {
if (city[i][j] == x) {
city[i][j] = 0;
}
sb.append(city[i][j]).append(" ");
}
sb.append("\n");
}
System.out.println(sb);
br.close();
}
}