-
Notifications
You must be signed in to change notification settings - Fork 229
/
Copy path1928-minimum-cost-to-reach-destination-in-time.js
105 lines (97 loc) · 2.49 KB
/
1928-minimum-cost-to-reach-destination-in-time.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* @param {number} maxTime
* @param {number[][]} edges
* @param {number[]} passingFees
* @return {number}
*/
const minCost = function(maxTime, edges, passingFees) {
const n = passingFees.length
const pq = new PriorityQueue((a, b) => a[0] < b[0])
const graph = {}
for(let [s, e, t] of edges) {
if(graph[s] == null) graph[s] = []
if(graph[e] == null) graph[e] = []
graph[s].push([e, t])
graph[e].push([s, t])
}
const times = {}
pq.push([passingFees[0], 0, 0])
while(!pq.isEmpty()) {
const [cost, node, time] = pq.pop()
if(time > maxTime) continue
if(node === n - 1) return cost
if(times[node] == null || times[node] > time) {
times[node] = time
for(let [nxt, ext] of graph[node]) {
pq.push([cost + passingFees[nxt], nxt, time + ext])
}
}
}
return -1
};
class PriorityQueue {
constructor(comparator = (a, b) => a > b) {
this.heap = []
this.top = 0
this.comparator = comparator
}
size() {
return this.heap.length
}
isEmpty() {
return this.size() === 0
}
peek() {
return this.heap[this.top]
}
push(...values) {
values.forEach((value) => {
this.heap.push(value)
this.siftUp()
})
return this.size()
}
pop() {
const poppedValue = this.peek()
const bottom = this.size() - 1
if (bottom > this.top) {
this.swap(this.top, bottom)
}
this.heap.pop()
this.siftDown()
return poppedValue
}
replace(value) {
const replacedValue = this.peek()
this.heap[this.top] = value
this.siftDown()
return replacedValue
}
parent = (i) => ((i + 1) >>> 1) - 1
left = (i) => (i << 1) + 1
right = (i) => (i + 1) << 1
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
siftUp = () => {
let node = this.size() - 1
while (node > this.top && this.greater(node, this.parent(node))) {
this.swap(node, this.parent(node))
node = this.parent(node)
}
}
siftDown = () => {
let node = this.top
while (
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
(this.right(node) < this.size() && this.greater(this.right(node), node))
) {
let maxChild =
this.right(node) < this.size() &&
this.greater(this.right(node), this.left(node))
? this.right(node)
: this.left(node)
this.swap(node, maxChild)
node = maxChild
}
}
}