11// 특정 거리의 도시 찾기
22// https://www.acmicpc.net/problem/18352
33
4+ class MinHeap {
5+ constructor ( ) {
6+ this . nodes = [ ] ;
7+ }
8+
9+ isEmpty ( ) {
10+ return this . nodes . length === 0 ;
11+ }
12+
13+ insert ( value ) {
14+ this . nodes . push ( value ) ;
15+ this . bubbleUp ( ) ;
16+ }
17+
18+ bubbleUp ( index = this . nodes . length - 1 ) {
19+ if ( index < 1 ) return ;
20+
21+ const currentNode = this . nodes [ index ] ;
22+ const parentIndex = Math . floor ( ( index - 1 ) / 2 ) ;
23+ const parentNode = this . nodes [ parentIndex ] ;
24+
25+ if ( parentNode [ 1 ] <= currentNode [ 1 ] ) return ;
26+
27+ this . nodes [ index ] = parentNode ;
28+ this . nodes [ parentIndex ] = currentNode ;
29+ index = parentIndex ;
30+ this . bubbleUp ( index ) ;
31+ }
32+
33+ extract ( ) {
34+ const min = this . nodes [ 0 ] ;
35+ if ( this . nodes . length === 1 ) {
36+ this . nodes . pop ( ) ;
37+ return min ;
38+ }
39+ this . nodes [ 0 ] = this . nodes . pop ( ) ;
40+ this . trickleDown ( ) ;
41+ return min ;
42+ }
43+
44+ trickleDown ( index = 0 ) {
45+ const leftChildIndex = 2 * index + 1 ;
46+ const rightChildIndex = 2 * index + 2 ;
47+ const length = this . nodes . length ;
48+ let minimum = index ;
49+
50+ if ( ! this . nodes [ rightChildIndex ] && ! this . nodes [ leftChildIndex ] ) return ;
51+ if ( ! this . nodes [ rightChildIndex ] ) {
52+ if ( this . nodes [ leftChildIndex ] [ 1 ] < this . nodes [ minimum ] [ 1 ] ) {
53+ minimum = leftChildIndex ;
54+ }
55+ return ;
56+ }
57+
58+ if ( this . nodes [ leftChildIndex ] [ 1 ] > this . nodes [ rightChildIndex ] [ 1 ] ) {
59+ if (
60+ rightChildIndex <= length &&
61+ this . nodes [ rightChildIndex ] [ 1 ] < this . nodes [ minimum ] [ 1 ]
62+ ) {
63+ minimum = rightChildIndex ;
64+ }
65+ } else {
66+ if (
67+ leftChildIndex <= length &&
68+ this . nodes [ leftChildIndex ] [ 1 ] < this . nodes [ minimum ] [ 1 ]
69+ ) {
70+ minimum = leftChildIndex ;
71+ }
72+ }
73+
74+ if ( minimum !== index ) {
75+ let t = this . nodes [ minimum ] ;
76+ this . nodes [ minimum ] = this . nodes [ index ] ;
77+ this . nodes [ index ] = t ;
78+ this . trickleDown ( minimum ) ;
79+ }
80+ }
81+ }
82+
483function dijkstra ( N , K , X , graph ) {
584 const visit = Array ( N + 1 ) . fill ( Infinity ) ;
6- const queue = [ ] ;
85+ const heap = new MinHeap ( ) ;
786
8- queue . push ( [ X , 0 ] ) ;
87+ heap . insert ( [ X , 0 ] ) ;
988
1089 visit [ X ] = 0 ;
1190
12- while ( queue . length !== 0 ) {
13- queue . sort ( ( a , b ) => {
14- return a [ 1 ] - b [ 1 ] ;
15- } ) ;
16-
17- const [ vertex , weight ] = queue . shift ( ) ;
91+ while ( ! heap . isEmpty ( ) ) {
92+ const [ vertex , weight ] = heap . extract ( ) ;
1893
1994 if ( weight > K ) {
2095 continue ;
@@ -23,7 +98,7 @@ function dijkstra(N, K, X, graph) {
2398 for ( let i = 0 ; i < graph [ vertex ] . length ; i ++ ) {
2499 if ( weight + 1 < visit [ graph [ vertex ] [ i ] ] ) {
25100 visit [ graph [ vertex ] [ i ] ] = weight + 1 ;
26- queue . push ( [ graph [ vertex ] [ i ] , weight + 1 ] ) ;
101+ heap . insert ( [ graph [ vertex ] [ i ] , weight + 1 ] ) ;
27102 }
28103 }
29104 }
@@ -90,6 +165,10 @@ console.log(dijkstra(N, K, X, graph));
90165
91166자바스크립트에는 기본으로 제공되는 우선순위 큐 자료구조가 없어서 루프를 돌 때 마다 정렬하는 식으로 타협을 봤다.
92167
168+ ---
169+
170+ 루프돌때 정렬하는 부분에 최소힙을 적용할 수 있을까 싶어서 최소힙을 적용해봤는데 의도한대로 작동하였다.
171+
93172## Retrospective
94173
95174*/
0 commit comments