1
+ //정답 1 - pereng11
2
+ // 다익스트라 + 최소힙 O( N * logN )
3
+ function solution ( N , road , K )
4
+ {
5
+ // [목적지, 거리] 노드를 값으로 가지는, 거리에 대한 최소힙
6
+ class MinHeap {
7
+ constructor ( )
8
+ {
9
+ this . heap = [ null ] ;
10
+ }
11
+ // 맨 끝에 노드를 삽입 후 위로 올라가면서 정렬
12
+ push ( val )
13
+ {
14
+ this . heap . push ( val ) ;
15
+ let childIdx = this . heap . length - 1 ;
16
+ let parentIdx = Math . floor ( childIdx / 2 ) ;
17
+ while ( parentIdx > 0 && this . heap [ parentIdx ] [ 1 ] > this . heap [ childIdx ] [ 1 ] ) {
18
+ this . swap ( childIdx , parentIdx ) ;
19
+ childIdx = parentIdx ;
20
+ parentIdx = Math . floor ( childIdx / 2 ) ;
21
+ }
22
+ }
23
+ pop ( )
24
+ {
25
+ if ( this . heap . length === 1 )
26
+ {
27
+ return undefined ;
28
+ }
29
+ // 최소값은 빼두었다가 리턴하고, 가장 끝 값을 맨 위로 가져와 아래로 내려가면서 정렬
30
+ const minNode = this . heap [ 1 ] ;
31
+ this . heap [ 1 ] = this . heap [ this . heap . length - 1 ] ;
32
+ this . heap . pop ( ) ;
33
+ let parentIdx = 1 ;
34
+ let leftChildIdx = 2 ;
35
+ let rightChildIdx = 3 ;
36
+ while ( parentIdx < this . heap . length )
37
+ {
38
+ // 자식이 없는 경우
39
+ if ( ! this . heap [ leftChildIdx ] )
40
+ {
41
+ break ;
42
+ } // 왼쪽 자식만 있는 경우
43
+ else if ( ! this . heap [ rightChildIdx ] )
44
+ {
45
+ if ( this . heap [ parentIdx ] [ 1 ] > this . heap [ leftChildIdx ] [ 1 ] )
46
+ {
47
+ this . swap ( parentIdx , leftChildIdx ) ;
48
+ }
49
+ break ;
50
+ // 둘 중 하나가 부모보다 작을 때, 더 작은 쪽으로 정렬
51
+ } else if ( this . heap [ parentIdx ] [ 1 ] > this . heap [ leftChildIdx ] [ 1 ] || this . heap [ parentIdx ] [ 1 ] > this . heap [ rightChildIdx ] [ 1 ] )
52
+ {
53
+ const minChildIdx = this . heap [ leftChildIdx ] [ 1 ] < this . heap [ rightChildIdx ] [ 1 ] ? leftChildIdx : rightChildIdx ;
54
+ this . swap ( parentIdx , minChildIdx ) ;
55
+ parentIdx = minChildIdx ;
56
+ leftChildIdx = parentIdx * 2
57
+ rightChildIdx = parentIdx * 2 + 1 ;
58
+ } else
59
+ {
60
+ // 끝까지 내려가지 않았더라도 부모가 가장 작으면 정렬 중지
61
+ break ;
62
+ }
63
+ }
64
+ return minNode ;
65
+ }
66
+ swap ( idx1 , idx2 )
67
+ {
68
+ [ this . heap [ idx1 ] , this . heap [ idx2 ] ] = [ this . heap [ idx2 ] , this . heap [ idx1 ] ] ;
69
+ }
70
+ length ( )
71
+ {
72
+ return this . heap . length ;
73
+ }
74
+ }
75
+
76
+
77
+ const roadsTable = { } ; //전체 도로 정보
78
+
79
+ // 도로 정보 초기화 roadTable[시작점] = [목적지, 거리] 배열
80
+ for ( let i = 1 ; i <= N ; i ++ )
81
+ {
82
+ roadsTable [ i ] = [ ] ;
83
+ }
84
+ road . forEach ( road =>
85
+ {
86
+ let [ sp , ep , dist ] = road ;
87
+ roadsTable [ sp ] . push ( [ ep , dist ] ) ;
88
+ roadsTable [ ep ] . push ( [ sp , dist ] ) ;
89
+ } ) ;
90
+
91
+ function djikstra ( sp )
92
+ {
93
+ const visited = new Array ( N + 1 ) . fill ( false ) ; //방문 확인 배열
94
+ const dist = new Array ( N + 1 ) . fill ( Infinity ) ; //목표지점까지 거리
95
+ const heap = new MinHeap ( ) ;
96
+
97
+ //시작점 삽입
98
+ heap . push ( [ sp , 0 ] ) ;
99
+
100
+ // 가장 가까운 목적지부터 순서대로 방문
101
+ while ( heap . length ( ) > 1 )
102
+ {
103
+ //힙에 저장된 목적지 중 가장 가까운 거리의 목적지를 꺼냄 [목적지, 거리]
104
+ const [ ep , val ] = heap . pop ( ) ;
105
+ //아직 방문하지 않은 곳만 처리
106
+ if ( ! visited [ ep ] )
107
+ {
108
+ //방문처리, 거리 저장
109
+ visited [ ep ] = true ;
110
+ dist [ ep ] = val ;
111
+ //방문 지점을 거쳐서 가는 다른 목적지 구하기
112
+ const nexts = roadsTable [ ep ] ;
113
+ if ( nexts )
114
+ {
115
+ nexts . forEach ( n =>
116
+ {
117
+ let [ nextEp , nextVal ] = n ;
118
+ if ( ! visited [ nextEp ] ) //아직 방문하지 않은 곳일 경우, '지금까지의 거리 + 현재 위치에서의 거리'로 힙에 삽입
119
+ {
120
+ heap . push ( [ nextEp , val + nextVal ] ) ;
121
+ }
122
+ } )
123
+ }
124
+ }
125
+ }
126
+ // 거리가 K이하인 지점의 개수 반환
127
+ const result = dist . filter ( d => d <= K ) . length ;
128
+ return result ;
129
+ }
130
+
131
+ const answer = djikstra ( 1 ) ;
132
+ return answer ;
133
+ }
134
+
135
+ //정답 2 - pereng11 O(N * N);
136
+ //다익스트라 + 선형탐색
137
+ function solution ( N , road , K )
138
+ {
139
+
140
+ const roadsTable = { } ; //전체 도로 정보
141
+
142
+ // 도로 정보 초기화 roadTable[시작점] = [목적지, 거리] 배열
143
+ for ( let i = 1 ; i <= N ; i ++ )
144
+ {
145
+ roadsTable [ i ] = [ ] ;
146
+ }
147
+ road . forEach ( road =>
148
+ {
149
+ let [ sp , ep , dist ] = road ;
150
+ roadsTable [ sp ] . push ( [ ep , dist ] ) ;
151
+ roadsTable [ ep ] . push ( [ sp , dist ] ) ;
152
+ } ) ;
153
+
154
+ function djikstra ( sp )
155
+ {
156
+ const dist = new Array ( N + 1 ) . fill ( Infinity ) ; //목표지점까지 거리
157
+ const queue = [ ] ;
158
+
159
+ queue . push ( [ sp , 0 ] ) ;
160
+
161
+ while ( queue . length > 0 )
162
+ {
163
+ const [ ep , val ] = queue . shift ( ) ;
164
+ if ( dist [ ep ] > val )
165
+ {
166
+ dist [ ep ] = val ;
167
+ const nexts = roadsTable [ ep ] ;
168
+ if ( nexts )
169
+ {
170
+ nexts . forEach ( n =>
171
+ {
172
+ let [ nextEp , nextVal ] = n ;
173
+ //거리가 더 줄어드는 경우, '지금까지의 거리 + 현재 위치에서의 거리'로 힙에 삽입
174
+ if ( dist [ nextEp ] > val + nextVal )
175
+ {
176
+ queue . push ( [ nextEp , val + nextVal ] ) ;
177
+ }
178
+ } ) ;
179
+ }
180
+ }
181
+ }
182
+ // 거리가 K이하인 지점의 개수 반환
183
+ const result = dist . filter ( d => d <= K ) . length ;
184
+ return result ;
185
+ }
186
+
187
+ const answer = djikstra ( 1 ) ;
188
+ return answer ;
189
+ }
0 commit comments