Problem Statement in English
You’re given a network of n nodes, represented as a directed graph with edges, where each edge has an associated cost. Each node can either be online or offline, represented by the boolean array online. You are also given an integer k, which represents the maximum total cost you can incur while traversing the network.
You start at node 0 and want to reach node n-1. You can only traverse edges that lead to online nodes (or the destination node n-1). Your task is to find the maximum possible minimum edge cost along any valid path from node 0 to node n-1 such that the total cost of the path does not exceed k. If no such path exists, return -1.
You cannot traverse through offline nodes, except for the destination node n-1. It is guaranteed that there is at least one path from node 0 to node n-1, and that both nodes 0 and n-1 are online.
Approach
To solve this problem we use the following approach: we guess a minimum edge cost and check if there exists a valid path from node 0 to node n-1 such that all edges in the path have a cost greater than or equal to the guessed value and the total cost of the path does not exceed k. Since the question wants the maximum possible minimum edge cost, we can use binary search over the unique edge costs to find the answer.
We thus break this into 2 parts:
Binary Search: We will perform a binary search over the unique edge costs to find the maximum possible minimum edge cost that allows a valid path from node
0to noden-1.DFS Check: For each guessed minimum edge cost, we will perform a depth-first search (DFS) to check if there exists a valid path from node
0to noden-1such that all edges in the path have a cost greater than or equal to the guessed value and the total cost of the path does not exceedk. We will also use memoization to optimize our DFS.
And we’re done!
Solution in Python
class Solution:
def findMaxPathScore(self, edges: List[List[int]], online: List[bool], k: int) -> int:
n = len(online)
# Build the adjacency list
adj = defaultdict(list)
unique_costs = set()
for u, v, cost in edges:
adj[u].append((v, cost))
unique_costs.add(cost)
# Possible scores sorted for binary search
possible_scores = sorted(list(unique_costs))
# Helper function to check if a valid path exists with a minimum edge cost >= target_score
def can_reach(target_score: int) -> bool:
# memo[u] will store the minimum path cost from u to n-1
memo = {}
def dfs(u):
if u == n - 1:
return 0
if u in memo:
return memo[u]
min_cost = float('inf')
for v, cost in adj[u]:
# Condition 1: Edge cost must be at least target_score
# Condition 2: Intermediate node must be online (or destination)
if cost >= target_score and (online[v] or v == n - 1):
min_cost = min(min_cost, cost + dfs(v))
memo[u] = min_cost
return min_cost
return dfs(0) <= k
# Binary search over the possible scores
low, high = 0, len(possible_scores) - 1
ans = -1
while low <= high:
mid = (low + high) // 2
if can_reach(possible_scores[mid]):
ans = possible_scores[mid] # Try to find a larger minimum edge cost
low = mid + 1
else:
high = mid - 1
return ans
Complexity
Time: $O((V + E) \log C)$
- $V$ is the number of nodes, $E$ is the number of edges, and $C$ is the number of unique edge costs.
Space: $O(V + E)$
- Since we store the adjacency list and memoization dictionary.
Mistakes I Made
I had to look this up :(
And we are done.