Skip to content

Commit 6f36d88

Browse files
authored
Update 1976-number-of-ways-to-arrive-at-destination.js
1 parent 88be6ff commit 6f36d88

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

1976-number-of-ways-to-arrive-at-destination.js

+111
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,114 @@ class PriorityQueue {
109109
}
110110
}
111111

112+
// another
113+
114+
/**
115+
* @param {number} n
116+
* @param {number[][]} roads
117+
* @return {number}
118+
*/
119+
const countPaths = function(n, roads) {
120+
const graph = {}, MOD = 1e9 + 7
121+
for(const [u, v, t] of roads) {
122+
if(graph[u] == null) graph[u] = {}
123+
if(graph[v] == null) graph[v] = {}
124+
graph[u][v] = t
125+
graph[v][u] = t
126+
}
127+
128+
return dijkstra(graph, n, 0)
129+
130+
function dijkstra(graph, n, src) {
131+
const dist = Array(n).fill(Infinity)
132+
const ways = Array(n).fill(0)
133+
ways[src] = 1
134+
dist[src] = 0
135+
const pq = new PriorityQueue((a, b) => a[0] < b[0])
136+
pq.push([0, 0])
137+
while(!pq.isEmpty()) {
138+
const [d, u] = pq.pop()
139+
if(d > dist[u]) continue
140+
for(const next of Object.keys(graph[u] || {})) {
141+
const val = graph[u][next]
142+
if(dist[next] > d + val) {
143+
dist[next] = d + val
144+
ways[next] = ways[u]
145+
pq.push([dist[next], next])
146+
} else if(dist[next] === d + val) {
147+
ways[next] = (ways[next] + ways[u]) % MOD
148+
}
149+
}
150+
}
151+
152+
return ways[n - 1]
153+
}
154+
};
155+
156+
class PriorityQueue {
157+
constructor(comparator = (a, b) => a > b) {
158+
this.heap = []
159+
this.top = 0
160+
this.comparator = comparator
161+
}
162+
size() {
163+
return this.heap.length
164+
}
165+
isEmpty() {
166+
return this.size() === 0
167+
}
168+
peek() {
169+
return this.heap[this.top]
170+
}
171+
push(...values) {
172+
values.forEach((value) => {
173+
this.heap.push(value)
174+
this.siftUp()
175+
})
176+
return this.size()
177+
}
178+
pop() {
179+
const poppedValue = this.peek()
180+
const bottom = this.size() - 1
181+
if (bottom > this.top) {
182+
this.swap(this.top, bottom)
183+
}
184+
this.heap.pop()
185+
this.siftDown()
186+
return poppedValue
187+
}
188+
replace(value) {
189+
const replacedValue = this.peek()
190+
this.heap[this.top] = value
191+
this.siftDown()
192+
return replacedValue
193+
}
194+
195+
parent = (i) => ((i + 1) >>> 1) - 1
196+
left = (i) => (i << 1) + 1
197+
right = (i) => (i + 1) << 1
198+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
199+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
200+
siftUp = () => {
201+
let node = this.size() - 1
202+
while (node > this.top && this.greater(node, this.parent(node))) {
203+
this.swap(node, this.parent(node))
204+
node = this.parent(node)
205+
}
206+
}
207+
siftDown = () => {
208+
let node = this.top
209+
while (
210+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
211+
(this.right(node) < this.size() && this.greater(this.right(node), node))
212+
) {
213+
let maxChild =
214+
this.right(node) < this.size() &&
215+
this.greater(this.right(node), this.left(node))
216+
? this.right(node)
217+
: this.left(node)
218+
this.swap(node, maxChild)
219+
node = maxChild
220+
}
221+
}
222+
}

0 commit comments

Comments
 (0)