๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”Ž Algorithm/๐Ÿ“ ๊ฐœ๋… ์ •๋ฆฌ

[๊ฐœ๋… ์ •๋ฆฌ] ์ตœ๋‹จ๊ฑฐ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ํ”Œ๋กœ์ด๋“œ ์™€์ƒฌ

by Seongpyo Hong 2021. 3. 16.

๊ฐ€์ค‘์น˜๊ฐ€ ์—†๋Š” ๊ทธ๋ž˜ํ”„์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋ฌธ์ œ๋Š” ๋Œ€๋ถ€๋ถ„ BFS๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๊ฐ„์„ ์— ๊ฐ€์ค‘์น˜๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด BFS๊ฐ€ ์•„๋‹Œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด ์ ‘๊ทผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์ค‘์น˜ ๊ทธ๋ž˜ํ”„์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์œ ํ˜•์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

  1. ๋‘ ์ •์  ๊ฐ„์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
  2. ํ•˜๋‚˜์˜ ์ •์ ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ •์ ๊ณผ์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
  3. ํ•˜๋‚˜์˜ ์ •์ ์œผ๋กœ ๊ฐ€๋Š” ๋ชจ๋“  ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ
  4. ์ •์  ๊ฐ„์˜ ๋ชจ๋“  ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ

์ด ์ค‘ 4๋ฒˆ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ํ”Œ๋กœ์ด๋“œ-์™€์ƒฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.


ํ”Œ๋กœ์ด๋“œ ์™€์ƒฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜

ํ”Œ๋กœ์ด๋“œ ์™€์ƒฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ชจ๋“  ์ •์ ๊ฐ„์˜ ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ์˜ ์„ค๋ช…์—์„œ ์‚ฌ์šฉ๋  ๊ทธ๋ž˜ํ”„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

๋ฐœ๋กœ ๊ทธ๋ฆฐ ๊ทธ๋ฆผ

 

์ดˆ๊ธฐ ๊ฐ€์ค‘์น˜ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ์ธ์ ‘ ํ–‰๋ ฌ(D)์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ธ์ ‘ ํ–‰๋ ฌ D

์ดˆ๊ธฐ ์ธ์ ‘ํ–‰๋ ฌ์„ ์ตœ๋‹จ ๊ฒฝ๋กœ ํ–‰๋ ฌ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด ๋ณด๋ฉด K๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ, ์ •์  i์—์„œ j๊นŒ์ง€์˜ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋Š” ๊ธฐ์กด์— i ⇒ j์˜ ๊ฑฐ๋ฆฌ์™€ ์ค‘๊ฐ„์— k๋ฅผ ๊ฑฐ์ณ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ ์ค‘ ์งง์€ ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์ ํ™”์‹์„ ํ†ตํ•ด ์ •์  i,j ๊ฐ„์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ์–ด๋–ค ์ •์ ์„ ๊ฑฐ์น˜๋Š”์ง€ ๊ฒฝ๋กœ๋ฅผ ์•Œ ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„์—์„œ๋Š” ์ง์ „ ์ •์  ํ–‰๋ ฌ(P)์„ ์œ ์ง€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ง์ „ ์ •์  ํ–‰๋ ฌ์ด๋ž€ i ์ •์ ์—์„œ j ์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ์—์„œ j ์ •์  ์ง์ „์— ์œ„์น˜ํ•˜๋Š” ์ •์ ์„ ์ €์žฅํ•˜๋Š” ํ–‰๋ ฌ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

์ดˆ๊ธฐ ์ง์ „ ์ •์  ํ–‰๋ ฌ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ง์ „ ์ •์  ํ–‰๋ ฌ P

์ธ์ ‘ ํ–‰๋ ฌ์„ ๊ฐฑ์‹ ํ•˜๋ฉด์„œ i,j์˜ ์ •์ ์‚ฌ์ด์—์„œ k๋ฅผ ๊ฑฐ์ณ ๊ฐ€๋Š” ๊ฒฝ๋กœ๊ฐ€ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ผ๋ฉด P(i,j)๋ฅผ k๋กœ ๊ฐฑ์‹ ํ•ด์ฃผ๋ฉด ๋ชจ๋“  ์ •์ ์ด ์ถ”๊ฐ€๋œ ์ดํ›„ ์ตœ๋‹จ ๊ฒฝ๋กœ์— ์†ํ•˜๋Š” ์ •์ ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ดํ›„ ์ฝ”๋“œ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.


Java ๊ตฌํ˜„

์ž๋ฐ”๋กœ ๊ตฌํ˜„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. Input์€ ๋ฐฑ์ค€ ํ”Œ๋กœ์ด๋“œ ๋ฌธ์ œ์™€ ๋™์ผํ•˜๊ฒŒ ์œ„์˜ ๊ทธ๋ž˜ํ”„๋ฅผ (start, destination, weight) ํ˜•ํƒœ๋กœ ๋ฐ›๋Š” ์ƒํ™ฉ์œผ๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Blog {
	static final int INF = 99999;
	static final int NIL = -1;
	static int[][] D = new int[6][6];
	static int[][] P = new int[6][6];
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

	public static void main(String[] args) throws IOException {
		// Initialize
		for (int i = 0; i < 6; i++) {
			for (int j = 0; j < 6; j++) {
				P[i][j] = NIL;
				D[i][j] = INF;
			}
		}

		// process input
		for (int i = 0; i < 8; i++) {
			String[] line = br.readLine().split(" ");
			int start = Integer.parseInt(line[0]);
			int dest = Integer.parseInt(line[1]);
			int weight = Integer.parseInt(line[2]);
			D[start][dest] = weight;
			P[start][dest] = start;
		}
		floydWarshall();
	}

	public static void floydWarshall() {
		for (int k = 1; k <= 5; k++) {
			for (int i = 1; i <= 5; i++) {
				for (int j = 1; j <= 5; j++) {
					if (D[i][j] <=  D[i][k] + D[k][j]) continue;
					D[i][j] = D[i][k] + D[k][j];
					P[i][j] = k;
				}
			}
		}
	}
}

 

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์–ป์€ ์ธ์ ‘ ํ–‰๋ ฌ๊ณผ ์ง์ „ ์ •์  ํ–‰๋ ฌ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Input
=================
1 2 3
1 4 4
2 3 7
2 5 5
4 2 2
4 5 2
5 1 1
5 3 3

Init
======= D ========
INF 3  INF 4  INF 
INF INF 7  INF 5  
INF INF INF INF INF 
INF 2  INF INF 2  
1  INF 3  INF INF 
======= P ========
-1 1  -1 1  -1 
-1 -1 2  -1 2  
-1 -1 -1 -1 -1 
-1 4  -1 -1 4  
5  -1 5  -1 -1 


Add :1
======= D ========
INF 3  INF 4  INF 
INF INF 7  INF 5  
INF INF INF INF INF 
INF 2  INF INF 2  
1  4  3  5  INF 
======= P ========
-1 1  -1 1  -1 
-1 -1 2  -1 2  
-1 -1 -1 -1 -1 
-1 4  -1 -1 4  
5  1  5  1  -1 


Add :2
======= D ========
INF 3  10  4  8  
INF INF 7  INF 5  
INF INF INF INF INF 
INF 2  9  INF 2  
1  4  3  5  9  
======= P ========
-1 1  2  1  2  
-1 -1 2  -1 2  
-1 -1 -1 -1 -1 
-1 4  2  -1 4  
5  1  5  1  2  


Add :3
======= D ========
INF 3  10  4  8  
INF INF 7  INF 5  
INF INF INF INF INF 
INF 2  9  INF 2  
1  4  3  5  9  
======= P ========
-1 1  2  1  2  
-1 -1 2  -1 2  
-1 -1 -1 -1 -1 
-1 4  2  -1 4  
5  1  5  1  2  


Add :4
======= D ========
INF 3  10  4  6  
INF INF 7  INF 5  
INF INF INF INF INF 
INF 2  9  INF 2  
1  4  3  5  7  
======= P ========
-1 1  2  1  4  
-1 -1 2  -1 2  
-1 -1 -1 -1 -1 
-1 4  2  -1 4  
5  1  5  1  4  


Add :5
======= D ========
7  3  9  4  6  
6  9  7  10  5  
INF INF INF INF INF 
3  2  5  7  2  
1  4  3  5  7  
======= P ========
5  1  5  1  4  
5  5  2  5  2  
-1 -1 -1 -1 -1 
5  4  5  5  4  
5  1  5  1  4

 

์ตœ๋‹จ ๊ฒฝ๋กœ์— ํ•ด๋‹นํ•˜๋Š” ์ •์ ์„ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ P[start][end]์˜ ๊ฐ’(์ง์ „ ์ •์ )์ด start์™€ ๊ฐ™์•„์งˆ ๋•Œ ๊นŒ์ง€ ๊ฐ’์„ ์ฐพ์•„๊ฐ€๋Š” ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.. 1 → 3์„ ์˜ˆ์‹œ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • P[1][3] = 5
  • P[1][5] = 4
  • P[1][4] = 1

์ด ๋•Œ ์ตœ์ข… ๊ฒฝ๋กœ๋Š” 1 ⇒ 4 ⇒ 5 ⇒ 3์ด ๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๊ณผ์ •์„ Java ์ฝ”๋“œ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

static void printPath(int start, int end) {
	Stack<Integer> path = new Stack<>();
	while(true) {
		path.add(end);
		if (P[start][end] == start) {
			path.add(start);
			break;
		}
		end = P[start][end];
	}
	while(!path.isEmpty()) 
		System.out.print(path.pop());
}

๋Œ“๊ธ€