๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
5๏ธโƒฃ CS/Algorithm

[Java Algorithm Note] ๋‹ค์ต์ŠคํŠธ๋ผ (feat. BOJ #1753 ์ตœ๋‹จ๊ฒฝ๋กœ)

by seolhee2750 2022. 8. 25.

์˜ค๋Š˜์€ ๊ทธ๋ž˜ํ”„, ๊ทธ๋ฆฌ๋””๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด๋ ค๊ตฌ ํ•œ๋‹ค.

์ด๋ฆ„์€ ๋„ˆ๋ฌด๋„ˆ๋ฌด ๋งŽ์ด ๋“ค์–ด๋ดค์ง€๋งŒ, ํ•œ๋ฒˆ๋„ ์ œ๋Œ€๋กœ ๊ณต๋ถ€ํ•ด๋ณธ์ ์€ ์—†๋Š”,,!!

 

๐Ÿ“Ž ๋‹ค์ต์ŠคํŠธ๋ผ(Dijkstra) ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‹ค์ต์ŠคํŠธ๋ผ๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

์ตœ๋‹จ ๊ฒฝ๋กœ
๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ, ๋‘ ์ •์  ์‚ฌ์ด์˜ ๊ฒฝ๋กœ๋“ค ์ค‘ ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ์ด ์ตœ์†Œ์ธ ๊ฒฝ๋กœ

 

๐Ÿ‘‰ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€,

ํ•˜๋‚˜์˜ ์‹œ์ž‘ ์ •์ ์—์„œ ๋ ์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์–˜๊ธฐํ•œ๋‹ค.

 

์•„๋ž˜ ๊ทธ๋ฆผ์„ ์˜ˆ๋กœ ๋ณด์ž.

A๊ฐ€ ์‹œ์ž‘์ ์ด๊ณ  C๊ฐ€ ๋ชฉ์ ์ง€๋ผ๊ณ  ํ•  ๋•Œ, ๊ฐ€์žฅ ๋จผ์ € A์— ์ธ์ ‘ํ•ด์žˆ๋Š” ์ •์ ์€ B์™€ C์ด๋‹ค.

์ด ๋•Œ A๊ฐ€ C๋กœ ๊ฐ€๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‘ ๊ฐ€์ง€ ์„ ํƒ์ง€๊ฐ€ ์ƒ๊ธด๋‹ค.

  1. ๋ฐ”๋กœ C๋กœ ๊ฐ€์ž!
  2. B๋ฅผ ๊ฑฐ์ณ์„œ C๋กœ ๊ฐ€์ž!

์œ„์˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด C๊ฐ€ ๋ฐ”๋กœ ์ธ์ ‘ํ•ด์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ ,

๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๋กœ ์ธํ•ด B๋ฅผ ๊ฑฐ์ณ C๋กœ ํ–ฅํ•˜๋Š” ๊ฒƒ์ด ๋” ์ตœ๋‹จ ๊ฒฝ๋กœ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

์œ„ ์˜ˆ์‹œ์˜ ๊ฒฝ์šฐ ๋‹จ์ˆœํžˆ B์ •์  ํ•˜๋‚˜๋งŒ์„ ๊ฑฐ์น˜๋ฉด ๋˜๋ฏ€๋กœ ๊ฐ„๋‹จํ•ด๋ณด์ด์ง€๋งŒ,

๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋งค์šฐ ๋งŽ์€ ์ˆซ์ž์˜ ์ •์ ์„ ์ง€๋‚˜๋Š” ๊ฒƒ์ด ๋” ์ตœ๋‹จ ๊ฒฝ๋กœ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.

 

๊ทธ๋Ÿด ๋•Œ์—๋Š” ํ•˜๋‚˜ ํ•˜๋‚˜ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ์ ธ๋ณด๋Š” ๊ฒƒ์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๋Š”๋ฐ,

์ด ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋ฐ”๋กœ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜! ๐Ÿ‘

 

๐Ÿ’ฅ ์ฃผ์˜ ์‚ฌํ•ญ

๊ทธ๋Ÿฐ๋ฐ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฒดํฌํ•ด์•ผ ํ•  ์ ์ด ์žˆ๋‹ค.

๋‹ค์ต์ŠคํŠธ๋ผ๋Š” '์Œ'์˜ ๊ฐ€์ค‘์น˜๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ ์Œ์˜ ๊ฐ€์ค‘์น˜๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฌธ์ œ์˜ ๊ฒฝ์šฐ ๋ฒจ๋งŒ-ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

์ด ์™ธ์—๋„ ํ”Œ๋กœ์ด๋“œ-์›Œ์ƒฌ ๊ฐ™์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•˜๋ฉด

์ข€ ๋” ํšจ์œจ์ ์œผ๋กœ ๋ชจ๋“  ์ •์ ๋“ค์— ๋Œ€ํ•œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•œ๋ฐ,

๋ฒจ๋งŒ ํฌ๋“œ์™€ ํ”Œ๋กœ์ด๋“œ ์›Œ์ƒฌ์€ ๋‹ค์Œ์—!! ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.


๐Ÿ“Ž ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„

๋‚˜๋Š” ๋ฐฑ์ค€ ์‚ฌ์ดํŠธ์˜ #1753 ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ–ˆ๋‹ค.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class BOJ_1753 {
	
	static class Node {
		int to, weight;
		
		public Node(int to, int weight) {
			this.to = to;
			this.weight = weight;
		}
	}
	
	static int V, E, S;
	static List<Node>[] list;
	static int[] dis;
	static boolean[] visited;
	
	public static void main(String[] args) throws Exception{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(in.readLine());
		StringBuilder out = new StringBuilder();
		
		V = Integer.parseInt(st.nextToken()); // ์ •์  ๊ฐœ์ˆ˜
		E = Integer.parseInt(st.nextToken()); // ๊ฐ„์„  ๊ฐœ์ˆ˜
		S = Integer.parseInt(in.readLine()) - 1; // ์‹œ์ž‘ ์ •์ 
		
		dis = new int[V];
		visited = new boolean[V];
		list = new ArrayList[V];
		for(int i = 0 ; i < V ; i++) {
			list[i] = new ArrayList<>();
		}
		
		for(int i = 0 ; i < E ; i++) {
			st = new StringTokenizer(in.readLine());
			int from = Integer.parseInt(st.nextToken()) - 1; // u
			int to = Integer.parseInt(st.nextToken()) - 1; // v
			int weight = Integer.parseInt(st.nextToken()); // ๊ฐ€์ค‘์น˜
			
			list[from].add(new Node(to, weight)); // ์œ ํ–ฅ ์ฒ˜๋ฆฌ
		}
		
		Arrays.fill(dis, Integer.MAX_VALUE);
		dis[S] = 0; // ์‹œ์ž‘์ ๋งŒ 0์œผ๋กœ ๋งŒ๋“ค๊ธฐ
		Dijk();
		
		for(int i = 0; i < V ; i++) {
			if(dis[i] == Integer.MAX_VALUE) out.append("INF" + "\n");
			else out.append(dis[i] + "\n");
		}
		
		System.out.print(out);
	}
	
	public static void Dijk() { // ๋‹ค์ต์ŠคํŠธ๋ผ
		PriorityQueue<Node> pq = new PriorityQueue<>((o1, o2) -> Integer.compare(o1.weight, o2.weight)); // ๊ฐ€์ค‘์น˜ ๊ธฐ์ค€ ์ •๋ ฌ
		pq.offer(new Node(S, 0));
		
		while(!pq.isEmpty()) {
			Node now = pq.poll();
			
			if(dis[now.to] < now.weight) continue;
			
			for(int i = 0; i < list[now.to].size(); i++) {
				Node next = list[now.to].get(i);
				
				if(dis[next.to] > now.weight + next.weight) {
					dis[next.to] = now.weight + next.weight;
					pq.offer(new Node(next.to, dis[next.to]));
				}
			}
		}
	}
}

/*
[test case]
5 6
1
5 1 1
1 2 2
1 3 3
2 3 4
2 4 5
3 4 6
*/

์ฝ”๋“œ ์ƒ๋‹จ์—์„œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ์„ค๋ช…ํ•ด๋ณด๊ฒ ๋‹ค.

 

โœ”๏ธ Node ํด๋ž˜์Šค

ํ•˜๋‚˜์˜ ์ •์ ์„ ํ‘œํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.

to(๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ )์™€ weight(๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ๊นŒ์ง€์˜ ๊ฐ€์ค‘์น˜)์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ๊ฐ€์ง„๋‹ค.

 

โœ”๏ธ ๋‹ค์ต์ŠคํŠธ๋ผ๋ฅผ ์œ„ํ•œ ์ค€๋น„๋ฌผ list, dis, visited

list๋Š” ๊ฐ ์ •์ ๋งˆ๋‹ค, ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ๋“ค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

dis๋Š” ๊ฐ ์ •์ ๋งˆ๋‹ค ์‹œ์ž‘์ ์—์„œ๋ถ€ํ„ฐ ์˜ค๋Š”๋ฐ ๊ฑธ๋ฆฐ ์ตœ๋‹จ ๊ฐ€์ค‘์น˜๋ฅผ ์ €์žฅํ•œ๋‹ค.

visited๋Š” ๊ฐ ์ •์ ๋งˆ๋‹ค ๋ฐฉ๋ฌธํ•œ์  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ €์žฅํ•œ๋‹ค.

 

โœ”๏ธ list ์ดˆ๊ธฐํ™”

์•„๋ž˜์— list ์ดˆ๊ธฐํ™”๊ฐ€ ์™„๋ฃŒ๋œ ๋ชจ์Šต์„ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ–ˆ๋‹ค.

list์˜ '์ธ๋ฑ์Šค == ์ •์  ๋ฒˆํ˜ธ'๋ผ๊ณ  ๊ฐ€์ •, ๊ฐ ์ •์ ๋งˆ๋‹ค ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ์˜ ์ •๋ณด๋“ค์„ ์ €์žฅํ•ด์ฃผ์—ˆ๋‹ค.

์ด ๋ฌธ์ œ์˜ ๊ฒฝ์šฐ ์œ ํ–ฅ ๊ทธ๋ž˜ํ”„์ด๋ฏ€๋กœ, ์ถœ๋ฐœํ•˜๋Š” ์ •์ ์— ๋„์ฐฉํ•˜๋Š” ์ •์ ์˜ ์ •๋ณด๋งŒ ์ €์žฅํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

โœ”๏ธ ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰ ์ „, ์ค€๋น„

dis ๋ฐฐ์—ด์€ ๊ณ„์†ํ•ด์„œ ์ตœ์†Ÿ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•ด์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ Intger.MAX_VALUE๋กœ ๋ชจ๋‘ ์ฑ„์›Œ์ฃผ์—ˆ๋‹ค.

์‹œ์ž‘์ ์— ํ•ด๋‹นํ•˜๋Š” ์ธ๋ฑ์Šค์—๋Š” 0์„ ์ €์žฅํ•ด์ฃผ์—ˆ๋‹ค. (์ž๊ธฐ ์ž์‹ ์—๊ฒŒ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ๋Š” ๋‹น์—ฐํžˆ 0์ด ์ตœ์†Œ๋‹ˆ๊นŒ!)

 

โœ”๏ธ ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰ Dijk() ๋ฉ”์„œ๋“œ

[1] PriorityQueue๋ฅผ ์ด์šฉํ•œ ์ •์ ๋งˆ๋‹ค์˜ ์ตœ์†Œ ๊ฒฝ๋กœ ํƒ์ƒ‰

Node ํƒ€์ž…์œผ๋กœ PriorityQueue๋ฅผ ๋งŒ๋“ค๊ณ , weight(๊ฐ€์ค‘์น˜)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜๋„๋ก ํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์‹œ์ž‘์ ์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ๋ณธ๊ฒฉ์ ์ธ ํƒ์ƒ‰ ์‹œ์ž‘ ์ „ ์ถ”๊ฐ€ํ–ˆ๋‹ค.
(*๊ผญ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ๋งค ๋ฒˆ ์ตœ์†Œ๊ฐ€ ๋˜๋Š” ๊ฒƒ๋งŒ ํ•„์š”ํ•œ ๊ฒฝ์šฐ

์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋Œ€๋ถ€๋ถ„ ๊ฐ€์žฅ ํšจ์œจ์ ์ด๋ฏ€๋กœ!! ์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์•„์šฉ)

 

[2] pq๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ ํƒ์ƒ‰

  • pq์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ(pq์— ์ €์žฅ๋œ ์ •์  ์ค‘ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฐ€์ง€๋Š” ์ •์ )๋ถ€ํ„ฐ ๊บผ๋‚ด์–ด now์— ๋‹ด์•˜๋‹ค.
  • now๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ(dis[now.to])๊ฐ€ now์˜ ๊ฐ€์ค‘์น˜๋ณด๋‹ค ์ž‘๋‹ค๋ฉด continue ํ–ˆ๋‹ค.
    (=> ์–ด์ฐจํ”ผ ์ด ๊ฒฝ๋กœ๋Š” ์ตœ๋‹จ์ด ๋  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋ฏ€๋กœ!)
  • ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ์—๋Š” now๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ์˜ list๋ฅผ ๋Œ๋ฉด์„œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ–ˆ๋‹ค.
    ๊ฐ€์žฅ ๋จผ์ € now๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ์ธ now.to๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ •์ ์ธ list[now.to].get(i)์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ next์— ๋‹ด์•˜๋‹ค.
    ๋งŒ์•ฝ dis[next]๊ฐ€ now์˜ ๊ฐ€์ค‘์น˜๊ณผ next์˜ ๊ฐ€์ค‘์น˜๋ฅผ ํ•ฉํ•œ ๊ฒƒ๋ณด๋‹ค ํฌ๋‹ค๋ฉด dis[next]๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ์—ˆ๊ณ ,
    ๊ทธ ๋‹ค์Œ์˜ ๊ฒฝ๋กœ ๋˜ํ•œ ํƒ์ƒ‰ํ•ด๋ณผ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•˜์—ฌ ๋‹ค์Œ ํƒ์ƒ‰์„ ์œ„ํ•œ ์ •๋ณด๋ฅผ pq์— ์ถ”๊ฐ€ํ–ˆ๋‹ค.

๐Ÿ‘€ ์ •๋ฆฌ

๋‹ค์ต์ŠคํŠธ๋ผ๋Š” ์–‘์˜ ๊ฐ€์ค‘์น˜๋งŒ์„ ๊ฐ€์ง€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰์— ์œ ์šฉํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

๋งค ํƒ์ƒ‰๋งˆ๋‹ค ๋” ์ ํ•ฉํ•œ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„๋‚˜๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ,

์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋‹ค.

 

โœ ์ถ”๊ฐ€

๋ฌธ์ œ๋ฅผ ๋” ํ’€์–ด๋ณด๋‹ค๋ณด๋‹ˆ,, ๊ทธ๋ƒฅ BFS๋กœ ํ‘ธ๋Š”๋ฐ,

Queue ๋Œ€์‹  PriorityQueue๋กœ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋‹ˆ๊นŒ ํ›จ์”ฌ ์ดํ•ด๊ฐ€ ์‰ฌ์› ๋‹ค !!

๋Œ“๊ธ€