Skip to content

Commit 200b9e4

Browse files
committed
Add solution
1 parent 7c1f27e commit 200b9e4

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// 3620. Network Recovery Pathways
2+
// You are given a directed acyclic graph of n nodes numbered from 0 to n − 1. This is represented by a 2D array edges of length m, where edges[i] = [ui, vi, costi] indicates a one‑way communication from node ui to node vi with a recovery cost of costi.
3+
// Some nodes may be offline. You are given a boolean array online where online[i] = true means node i is online. Nodes 0 and n − 1 are always online.
4+
// A path from 0 to n − 1 is valid if:
5+
// All intermediate nodes on the path are online.
6+
// The total recovery cost of all edges on the path does not exceed k.
7+
// For each valid path, define its score as the minimum edge‑cost along that path.
8+
// Return the maximum path score (i.e., the largest minimum-edge cost) among all valid paths. If no valid path exists, return -1.
9+
10+
11+
// Solution: Binary Search & Topological Sort
12+
13+
// Binary search for the maximum minimum edge cost.
14+
// For a minimum edge cost x, use topological sort to check if we can reach n-1 in less than k total score.
15+
16+
// Start off with nodes with no inbound edges.
17+
// Traverse neighbor nodes and only queue the neighbor if we have used all inbound edges.
18+
// Record the minimum cost to reach each node.
19+
20+
// Note: This solution is TLE, passes 626/636 test cases.
21+
// n = number of nodes, m = max(edge cost), e = number of edges
22+
// Time Complexity: O((n + e) log(m))
23+
// Space Complexity: O(n + e)
24+
function findMaxPathScore(edges, online, k) {
25+
const n = online.length, graph = Array(n).fill(0).map(() => []);
26+
const initialIndegrees = Array(n).fill(0);
27+
let maxCost = 0;
28+
for (let [u, v, cost] of edges) {
29+
if (online[u] && online[v]) {
30+
graph[u].push([v, cost]);
31+
initialIndegrees[v]++;
32+
maxCost = Math.max(maxCost, cost);
33+
}
34+
}
35+
const initialQueue = [];
36+
for (let i = 0; i < n; i++) {
37+
if (initialIndegrees[i] === 0) {
38+
initialQueue.push(i);
39+
}
40+
}
41+
let low = 0, high = maxCost, res = -1;
42+
while (low < high) {
43+
const mid = Math.ceil((low + high) / 2);
44+
if (canReachTarget(mid)) {
45+
low = mid;
46+
res = mid;
47+
} else {
48+
high = mid - 1;
49+
}
50+
}
51+
return res;
52+
53+
function canReachTarget(x) {
54+
const queue = [...initialQueue], indegrees = [...initialIndegrees];
55+
const minCost = Array(n).fill(Infinity);
56+
minCost[0] = 0;
57+
while (queue.length) {
58+
let node = queue.shift();
59+
for (let [nei, cost] of graph[node]) {
60+
if (cost >= x) {
61+
minCost[nei] = Math.min(minCost[nei], minCost[node] + cost);
62+
}
63+
if (--indegrees[nei] === 0) {
64+
queue.push(nei);
65+
}
66+
}
67+
}
68+
return minCost[n - 1] <= k;
69+
}
70+
};
71+
72+
// Two test cases
73+
console.log(findMaxPathScore([[0,1,5],[1,3,10],[0,2,3],[2,3,4]], [true,true,true,true], 10)) // 3
74+
console.log(findMaxPathScore([[0,1,7],[1,4,5],[0,2,6],[2,3,6],[3,4,2],[2,4,6]], [true,true,true,false,true], 12)) // 6

0 commit comments

Comments
 (0)