There is an undirected graph with n
nodes numbered from 0
to n - 1
(inclusive). You are given a 0-indexed integer array values
where values[i]
is the value of the ith
node. You are also given a 0-indexed 2D integer array edges
, where each edges[j] = [uj, vj, timej]
indicates that there is an undirected edge between the nodes uj
and vj
, and it takes timej
seconds to travel between the two nodes. Finally, you are given an integer maxTime
.
A valid path in the graph is any path that starts at node 0
, ends at node 0
, and takes at most maxTime
seconds to complete. You may visit the same node multiple times. The quality of a valid path is the sum of the values of the unique nodes visited in the path (each node's value is added at most once to the sum).
Return the maximum quality of a valid path.
Note: There are at most four edges connected to each node.
Example 1:
Input: values = [0,32,10,43], edges = [[0,1,10],[1,2,15],[0,3,10]], maxTime = 49 Output: 75 Explanation: One possible path is 0 -> 1 -> 0 -> 3 -> 0. The total time taken is 10 + 10 + 10 + 10 = 40 <= 49. The nodes visited are 0, 1, and 3, giving a maximal path quality of 0 + 32 + 43 = 75.
Example 2:
Input: values = [5,10,15,20], edges = [[0,1,10],[1,2,10],[0,3,10]], maxTime = 30 Output: 25 Explanation: One possible path is 0 -> 3 -> 0. The total time taken is 10 + 10 = 20 <= 30. The nodes visited are 0 and 3, giving a maximal path quality of 5 + 20 = 25.
Example 3:
Input: values = [1,2,3,4], edges = [[0,1,10],[1,2,11],[2,3,12],[1,3,13]], maxTime = 50 Output: 7 Explanation: One possible path is 0 -> 1 -> 3 -> 1 -> 0. The total time taken is 10 + 13 + 13 + 10 = 46 <= 50. The nodes visited are 0, 1, and 3, giving a maximal path quality of 1 + 2 + 4 = 7.
Constraints:
n == values.length
1 <= n <= 1000
0 <= values[i] <= 108
0 <= edges.length <= 2000
edges[j].length == 3
0 <= uj < vj <= n - 1
10 <= timej, maxTime <= 100
[uj, vj]
are unique.This problem asks to find the maximum quality of a path in a graph, starting and ending at node 0, with a maximum allowed time. The quality is the sum of unique node values visited.
Approach: Depth-First Search (DFS)
The most efficient approach is to use Depth-First Search (DFS) to explore all possible paths within the time constraint. Since the maximum time is relatively small and each node has at most four edges, a brute-force DFS is feasible.
Algorithm:
Graph Representation: Represent the graph using an adjacency list. Each node stores a list of its neighbors and the corresponding edge weights (times).
DFS Function: The core of the solution is a recursive DFS function: dfs(u, cost, value, visited)
:
u
: The current node.cost
: The accumulated time cost of the path so far.value
: The accumulated quality (sum of unique node values) of the path so far.visited
: A set to track visited nodes (to ensure unique node value summation).Base Case: If the current node u
is 0 (the starting node) and we've returned, update the maximum quality (ans
) if the current path's quality is higher.
Recursive Step: For each neighbor v
of the current node u
, check if adding the edge time to the current cost exceeds maxTime
. If not:
v
is already visited, recursively call dfs(v, cost + time, value, visited)
.v
is not visited, add it to visited
, update value
with values[v]
, recursively call dfs(v, cost + time, value, visited)
, and then remove v
from visited
(backtracking).Initialization: Start the DFS from node 0 with initial cost 0, value values[0]
, and an empty visited set.
Time and Space Complexity:
maxTime
. The exponential factor comes from the branching in the DFS; in the worst case, we explore all possible paths, which can grow exponentially with the maximum allowed time. The min_time
is the shortest edge weight which limits the maximum depth of the DFS tree.T/min_time
) and the adjacency list.Code (Python):
def maximalPathQuality(values, edges, maxTime):
n = len(values)
graph = [[] for _ in range(n)]
for u, v, t in edges:
graph[u].append((v, t))
graph[v].append((u, t))
ans = 0
def dfs(u, cost, value, visited):
nonlocal ans
if u == 0:
ans = max(ans, value)
return
for v, t in graph[u]:
if cost + t <= maxTime:
new_visited = set(visited)
if v not in new_visited:
new_visited.add(v)
dfs(v, cost + t, value + values[v], new_visited)
else:
dfs(v, cost + t, value, new_visited)
visited = {0}
dfs(0, 0, values[0], visited)
return ans
The code in other languages (Java, C++, Go, TypeScript) follows a very similar structure, using their respective data structures and syntax. The key algorithmic idea remains the same – a depth-first search that explores paths within the time constraint and tracks visited nodes for quality calculation.