Skip to content

Commit c349e00

Browse files
authored
Create 2699-modify-graph-edge-weights.js
1 parent 7f83ec0 commit c349e00

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

2699-modify-graph-edge-weights.js

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
class PQ {
2+
constructor(comparator = (a, b) => a > b) {
3+
this.heap = []
4+
this.top = 0
5+
this.comparator = comparator
6+
}
7+
size() {
8+
return this.heap.length
9+
}
10+
isEmpty() {
11+
return this.size() === 0
12+
}
13+
peek() {
14+
return this.heap[this.top]
15+
}
16+
push(...values) {
17+
values.forEach((value) => {
18+
this.heap.push(value)
19+
this.siftUp()
20+
})
21+
return this.size()
22+
}
23+
pop() {
24+
const poppedValue = this.peek()
25+
const bottom = this.size() - 1
26+
if (bottom > this.top) {
27+
this.swap(this.top, bottom)
28+
}
29+
this.heap.pop()
30+
this.siftDown()
31+
return poppedValue
32+
}
33+
replace(value) {
34+
const replacedValue = this.peek()
35+
this.heap[this.top] = value
36+
this.siftDown()
37+
return replacedValue
38+
}
39+
40+
parent = (i) => ((i + 1) >>> 1) - 1
41+
left = (i) => (i << 1) + 1
42+
right = (i) => (i + 1) << 1
43+
greater = (i, j) => this.comparator(this.heap[i], this.heap[j])
44+
swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]])
45+
siftUp = () => {
46+
let node = this.size() - 1
47+
while (node > this.top && this.greater(node, this.parent(node))) {
48+
this.swap(node, this.parent(node))
49+
node = this.parent(node)
50+
}
51+
}
52+
siftDown = () => {
53+
let node = this.top
54+
while (
55+
(this.left(node) < this.size() && this.greater(this.left(node), node)) ||
56+
(this.right(node) < this.size() && this.greater(this.right(node), node))
57+
) {
58+
let maxChild =
59+
this.right(node) < this.size() &&
60+
this.greater(this.right(node), this.left(node))
61+
? this.right(node)
62+
: this.left(node)
63+
this.swap(node, maxChild)
64+
node = maxChild
65+
}
66+
}
67+
}
68+
/**
69+
* @param {number} n
70+
* @param {number[][]} edges
71+
* @param {number} source
72+
* @param {number} destination
73+
* @param {number} target
74+
* @return {number[][]}
75+
*/
76+
const modifiedGraphEdges = function (n, edges, source, destination, target) {
77+
const kMax = Number.MAX_SAFE_INTEGER
78+
const graph = Array(n)
79+
.fill(null)
80+
.map(() => [])
81+
82+
for (const [u, v, w] of edges) {
83+
if (w === -1) {
84+
continue
85+
}
86+
graph[u].push([v, w])
87+
graph[v].push([u, w])
88+
}
89+
90+
const distToDestination = dijkstra(graph, source, destination)
91+
if (distToDestination < target) {
92+
return []
93+
}
94+
if (distToDestination === target) {
95+
// Change the weights of negative edges to an impossible value.
96+
for (const edge of edges) {
97+
if (edge[2] === -1) {
98+
edge[2] = kMax
99+
}
100+
}
101+
return edges
102+
}
103+
104+
for (let i = 0; i < edges.length; i++) {
105+
const [u, v, w] = edges[i]
106+
if (w !== -1) {
107+
continue
108+
}
109+
edges[i][2] = 1
110+
graph[u].push([v, 1])
111+
graph[v].push([u, 1])
112+
const distToDestination = dijkstra(graph, source, destination)
113+
if (distToDestination <= target) {
114+
edges[i][2] += target - distToDestination
115+
// Change the weights of negative edges to an impossible value.
116+
for (let j = i + 1; j < edges.length; j++) {
117+
if (edges[j][2] === -1) {
118+
edges[j][2] = kMax
119+
}
120+
}
121+
return edges
122+
}
123+
}
124+
125+
return []
126+
}
127+
128+
function dijkstra(graph, src, dst) {
129+
const dist = Array(graph.length).fill(Infinity)
130+
const minHeap = new PQ((a, b) => a[0] < b[0])
131+
132+
dist[src] = 0
133+
minHeap.push([dist[src], src])
134+
135+
while (!minHeap.isEmpty()) {
136+
const [d, u] = minHeap.pop()
137+
for (const [v, w] of graph[u] || []) {
138+
if (d + w < dist[v]) {
139+
dist[v] = d + w
140+
minHeap.push([dist[v], v])
141+
}
142+
}
143+
}
144+
145+
return dist[dst]
146+
}

0 commit comments

Comments
 (0)