diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/README.md b/solution/2000-2099/2065.Maximum Path Quality of a Graph/README.md index 21b63ca87a19a..1d43c5a7acd3a 100644 --- a/solution/2000-2099/2065.Maximum Path Quality of a Graph/README.md +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/README.md @@ -100,46 +100,209 @@ tags: -### 方法一 +### 方法一:DFS + +我们观察题目的数据范围,可以发现从 $0$ 开始的每条合法路径的边数不超过 $\frac{\text{maxTime}}{\min(time_j)} = \frac{100}{10} = 10$ 条,并且每个节点至多有四条边,所以我们可以直接使用朴素的 DFS 暴力搜索所有合法路径。 + +我们先将图的边存储在邻接表表 $g$ 中,然后我们设计一个函数 $\text{dfs}(u, \text{cost}, \text{value})$,其中 $u$ 表示当前节点编号,而 $\text{cost}$ 和 $\text{value}$ 分别表示当前路径的花费时间和价值。另外,使用一个长度为 $n$ 的数组 $\text{vis}$ 记录每个节点是否被访问过。初始时,我们将节点 $0$ 标记为已访问。 + +函数 $\text{dfs}(u, \text{cost}, \text{value})$ 的逻辑如下: + +- 如果当前节点编号 $u$ 等于 $0$,表示我们已经回到了起点,那么我们更新答案为 $\max(\text{ans}, \text{value})$; +- 遍历当前节点 $u$ 的所有邻居节点 $v$,如果当前路径的花费时间加上边 $(u, v)$ 的时间 $t$ 不超过 $\text{maxTime}$,那么我们可以选择继续访问节点 $v$; + - 如果节点 $v$ 已经被访问过,那么我们直接递归调用 $\text{dfs}(v, \text{cost} + t, \text{value})$; + - 如果节点 $v$ 没有被访问过,我们标记节点 $v$ 为已访问,然后递归调用 $\text{dfs}(v, \text{cost} + t, \text{value} + \text{values}[v])$,最后恢复节点 $v$ 的访问状态。 + +在主函数中,我们调用 $\text{dfs}(0, 0, \text{values}[0])$,并返回答案 $\text{ans}$ 即可。 + +时间复杂度 $O(n + m + 4^{\frac{\text{maxTime}}{\min(time_j)}})$,空间复杂度 $O(n + m + \frac{\text{maxTime}}{\min(time_j)})$。其中 $n$ 和 $m$ 分别表示节点数和边数。 +#### Python3 + +```python +class Solution: + def maximalPathQuality( + self, values: List[int], edges: List[List[int]], maxTime: int + ) -> int: + def dfs(u: int, cost: int, value: int): + if u == 0: + nonlocal ans + ans = max(ans, value) + for v, t in g[u]: + if cost + t <= maxTime: + if vis[v]: + dfs(v, cost + t, value) + else: + vis[v] = True + dfs(v, cost + t, value + values[v]) + vis[v] = False + + n = len(values) + g = [[] for _ in range(n)] + for u, v, t in edges: + g[u].append((v, t)) + g[v].append((u, t)) + vis = [False] * n + vis[0] = True + ans = 0 + dfs(0, 0, values[0]) + return ans +``` + +#### Java + +```java +class Solution { + private List[] g; + private boolean[] vis; + private int[] values; + private int maxTime; + private int ans; + + public int maximalPathQuality(int[] values, int[][] edges, int maxTime) { + int n = values.length; + g = new List[n]; + Arrays.setAll(g, k -> new ArrayList<>()); + for (var e : edges) { + int u = e[0], v = e[1], t = e[2]; + g[u].add(new int[] {v, t}); + g[v].add(new int[] {u, t}); + } + vis = new boolean[n]; + vis[0] = true; + this.values = values; + this.maxTime = maxTime; + dfs(0, 0, values[0]); + return ans; + } + + private void dfs(int u, int cost, int value) { + if (u == 0) { + ans = Math.max(ans, value); + } + for (var e : g[u]) { + int v = e[0], t = e[1]; + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(v, cost + t, value); + } else { + vis[v] = true; + dfs(v, cost + t, value + values[v]); + vis[v] = false; + } + } + } + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int maximalPathQuality(vector& values, vector>& edges, int maxTime) { + int n = values.size(); + vector> g[n]; + for (auto& e : edges) { + int u = e[0], v = e[1], t = e[2]; + g[u].emplace_back(v, t); + g[v].emplace_back(u, t); + } + bool vis[n]; + memset(vis, false, sizeof(vis)); + vis[0] = true; + int ans = 0; + auto dfs = [&](auto&& dfs, int u, int cost, int value) -> void { + if (u == 0) { + ans = max(ans, value); + } + for (auto& [v, t] : g[u]) { + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(dfs, v, cost + t, value); + } else { + vis[v] = true; + dfs(dfs, v, cost + t, value + values[v]); + vis[v] = false; + } + } + } + }; + dfs(dfs, 0, 0, values[0]); + return ans; + } +}; +``` + +#### Go + +```go +func maximalPathQuality(values []int, edges [][]int, maxTime int) (ans int) { + n := len(values) + g := make([][][2]int, n) + for _, e := range edges { + u, v, t := e[0], e[1], e[2] + g[u] = append(g[u], [2]int{v, t}) + g[v] = append(g[v], [2]int{u, t}) + } + vis := make([]bool, n) + vis[0] = true + var dfs func(u, cost, value int) + dfs = func(u, cost, value int) { + if u == 0 { + ans = max(ans, value) + } + for _, e := range g[u] { + v, t := e[0], e[1] + if cost+t <= maxTime { + if vis[v] { + dfs(v, cost+t, value) + } else { + vis[v] = true + dfs(v, cost+t, value+values[v]) + vis[v] = false + } + } + } + } + dfs(0, 0, values[0]) + return +} +``` + #### TypeScript ```ts function maximalPathQuality(values: number[], edges: number[][], maxTime: number): number { const n = values.length; - let g: Array>> = Array.from({ length: n }, v => new Array()); - for (let edge of edges) { - let [u, v, t] = edge; + const g: [number, number][][] = Array.from({ length: n }, () => []); + for (const [u, v, t] of edges) { g[u].push([v, t]); g[v].push([u, t]); } - let visited = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); + vis[0] = true; let ans = 0; - - function dfs(u: number, time: number, value: number): void { - // 索引0为终点 - if (!u) { - ans = Math.max(value, ans); + const dfs = (u: number, cost: number, value: number) => { + if (u === 0) { + ans = Math.max(ans, value); } - for (let [v, dist] of g[u]) { - if (time - dist >= 0) { - if (!visited[v]) { - visited[v] = true; - dfs(v, time - dist, value + values[v]); - visited[v] = false; // 回溯 + for (const [v, t] of g[u]) { + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(v, cost + t, value); } else { - dfs(v, time - dist, value); + vis[v] = true; + dfs(v, cost + t, value + values[v]); + vis[v] = false; } } } - } - - // 索引0为起点 - visited[0] = true; - dfs(0, maxTime, values[0]); - + }; + dfs(0, 0, values[0]); return ans; } ``` diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/README_EN.md b/solution/2000-2099/2065.Maximum Path Quality of a Graph/README_EN.md index ede563a026d37..65daca6cdcbc3 100644 --- a/solution/2000-2099/2065.Maximum Path Quality of a Graph/README_EN.md +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/README_EN.md @@ -81,46 +81,209 @@ The nodes visited are 0, 1, and 3, giving a maximal path quality of 1 + 2 + 4 = -### Solution 1 +### Solution 1: DFS + +We observe the data range of the problem and find that the number of edges in each valid path starting from $0$ does not exceed $\frac{\text{maxTime}}{\min(time_j)} = \frac{100}{10} = 10$, and each node has at most four edges. Therefore, we can directly use naive DFS to brute-force search all valid paths. + +First, we store the edges of the graph in the adjacency list $g$. Then, we design a function $\text{dfs}(u, \text{cost}, \text{value})$, where $u$ represents the current node number, and $\text{cost}$ and $\text{value}$ respectively represent the cost time and value of the current path. Additionally, we use an array $\text{vis}$ of length $n$ to record whether each node has been visited. Initially, we mark node $0$ as visited. + +The logic of the function $\text{dfs}(u, \text{cost}, \text{value})$ is as follows: + +- If the current node number $u$ equals $0$, it means we have returned to the starting point, so we update the answer to $\max(\text{ans}, \text{value})$; +- For each neighbor node $v$ of the current node $u$, if the current path's cost time plus the time $t$ of the edge $(u, v)$ does not exceed $\text{maxTime}$, then we can choose to continue visiting node $v$; + - If node $v$ has already been visited, we directly recursively call $\text{dfs}(v, \text{cost} + t, \text{value})$; + - If node $v$ has not been visited, we mark node $v$ as visited, then recursively call $\text{dfs}(v, \text{cost} + t, \text{value} + \text{values}[v])$, and finally restore the visit status of node $v$. + +In the main function, we call $\text{dfs}(0, 0, \text{values}[0])$ and return the answer $\text{ans}$. + +The time complexity is $O(n + m + 4^{\frac{\text{maxTime}}{\min(time_j)}})$, and the space complexity is $O(n + m + \frac{\text{maxTime}}{\min(time_j)})$. Here, $n$ and $m$ respectively represent the number of nodes and edges. +#### Python3 + +```python +class Solution: + def maximalPathQuality( + self, values: List[int], edges: List[List[int]], maxTime: int + ) -> int: + def dfs(u: int, cost: int, value: int): + if u == 0: + nonlocal ans + ans = max(ans, value) + for v, t in g[u]: + if cost + t <= maxTime: + if vis[v]: + dfs(v, cost + t, value) + else: + vis[v] = True + dfs(v, cost + t, value + values[v]) + vis[v] = False + + n = len(values) + g = [[] for _ in range(n)] + for u, v, t in edges: + g[u].append((v, t)) + g[v].append((u, t)) + vis = [False] * n + vis[0] = True + ans = 0 + dfs(0, 0, values[0]) + return ans +``` + +#### Java + +```java +class Solution { + private List[] g; + private boolean[] vis; + private int[] values; + private int maxTime; + private int ans; + + public int maximalPathQuality(int[] values, int[][] edges, int maxTime) { + int n = values.length; + g = new List[n]; + Arrays.setAll(g, k -> new ArrayList<>()); + for (var e : edges) { + int u = e[0], v = e[1], t = e[2]; + g[u].add(new int[] {v, t}); + g[v].add(new int[] {u, t}); + } + vis = new boolean[n]; + vis[0] = true; + this.values = values; + this.maxTime = maxTime; + dfs(0, 0, values[0]); + return ans; + } + + private void dfs(int u, int cost, int value) { + if (u == 0) { + ans = Math.max(ans, value); + } + for (var e : g[u]) { + int v = e[0], t = e[1]; + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(v, cost + t, value); + } else { + vis[v] = true; + dfs(v, cost + t, value + values[v]); + vis[v] = false; + } + } + } + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int maximalPathQuality(vector& values, vector>& edges, int maxTime) { + int n = values.size(); + vector> g[n]; + for (auto& e : edges) { + int u = e[0], v = e[1], t = e[2]; + g[u].emplace_back(v, t); + g[v].emplace_back(u, t); + } + bool vis[n]; + memset(vis, false, sizeof(vis)); + vis[0] = true; + int ans = 0; + auto dfs = [&](auto&& dfs, int u, int cost, int value) -> void { + if (u == 0) { + ans = max(ans, value); + } + for (auto& [v, t] : g[u]) { + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(dfs, v, cost + t, value); + } else { + vis[v] = true; + dfs(dfs, v, cost + t, value + values[v]); + vis[v] = false; + } + } + } + }; + dfs(dfs, 0, 0, values[0]); + return ans; + } +}; +``` + +#### Go + +```go +func maximalPathQuality(values []int, edges [][]int, maxTime int) (ans int) { + n := len(values) + g := make([][][2]int, n) + for _, e := range edges { + u, v, t := e[0], e[1], e[2] + g[u] = append(g[u], [2]int{v, t}) + g[v] = append(g[v], [2]int{u, t}) + } + vis := make([]bool, n) + vis[0] = true + var dfs func(u, cost, value int) + dfs = func(u, cost, value int) { + if u == 0 { + ans = max(ans, value) + } + for _, e := range g[u] { + v, t := e[0], e[1] + if cost+t <= maxTime { + if vis[v] { + dfs(v, cost+t, value) + } else { + vis[v] = true + dfs(v, cost+t, value+values[v]) + vis[v] = false + } + } + } + } + dfs(0, 0, values[0]) + return +} +``` + #### TypeScript ```ts function maximalPathQuality(values: number[], edges: number[][], maxTime: number): number { const n = values.length; - let g: Array>> = Array.from({ length: n }, v => new Array()); - for (let edge of edges) { - let [u, v, t] = edge; + const g: [number, number][][] = Array.from({ length: n }, () => []); + for (const [u, v, t] of edges) { g[u].push([v, t]); g[v].push([u, t]); } - let visited = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); + vis[0] = true; let ans = 0; - - function dfs(u: number, time: number, value: number): void { - // 索引0为终点 - if (!u) { - ans = Math.max(value, ans); + const dfs = (u: number, cost: number, value: number) => { + if (u === 0) { + ans = Math.max(ans, value); } - for (let [v, dist] of g[u]) { - if (time - dist >= 0) { - if (!visited[v]) { - visited[v] = true; - dfs(v, time - dist, value + values[v]); - visited[v] = false; // 回溯 + for (const [v, t] of g[u]) { + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(v, cost + t, value); } else { - dfs(v, time - dist, value); + vis[v] = true; + dfs(v, cost + t, value + values[v]); + vis[v] = false; } } } - } - - // 索引0为起点 - visited[0] = true; - dfs(0, maxTime, values[0]); - + }; + dfs(0, 0, values[0]); return ans; } ``` diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.cpp b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.cpp new file mode 100644 index 0000000000000..e39e7a56db75a --- /dev/null +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.cpp @@ -0,0 +1,34 @@ +class Solution { +public: + int maximalPathQuality(vector& values, vector>& edges, int maxTime) { + int n = values.size(); + vector> g[n]; + for (auto& e : edges) { + int u = e[0], v = e[1], t = e[2]; + g[u].emplace_back(v, t); + g[v].emplace_back(u, t); + } + bool vis[n]; + memset(vis, false, sizeof(vis)); + vis[0] = true; + int ans = 0; + auto dfs = [&](auto&& dfs, int u, int cost, int value) -> void { + if (u == 0) { + ans = max(ans, value); + } + for (auto& [v, t] : g[u]) { + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(dfs, v, cost + t, value); + } else { + vis[v] = true; + dfs(dfs, v, cost + t, value + values[v]); + vis[v] = false; + } + } + } + }; + dfs(dfs, 0, 0, values[0]); + return ans; + } +}; \ No newline at end of file diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.go b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.go new file mode 100644 index 0000000000000..707a338f055d3 --- /dev/null +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.go @@ -0,0 +1,31 @@ +func maximalPathQuality(values []int, edges [][]int, maxTime int) (ans int) { + n := len(values) + g := make([][][2]int, n) + for _, e := range edges { + u, v, t := e[0], e[1], e[2] + g[u] = append(g[u], [2]int{v, t}) + g[v] = append(g[v], [2]int{u, t}) + } + vis := make([]bool, n) + vis[0] = true + var dfs func(u, cost, value int) + dfs = func(u, cost, value int) { + if u == 0 { + ans = max(ans, value) + } + for _, e := range g[u] { + v, t := e[0], e[1] + if cost+t <= maxTime { + if vis[v] { + dfs(v, cost+t, value) + } else { + vis[v] = true + dfs(v, cost+t, value+values[v]) + vis[v] = false + } + } + } + } + dfs(0, 0, values[0]) + return +} \ No newline at end of file diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.java b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.java new file mode 100644 index 0000000000000..54635a279757d --- /dev/null +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.java @@ -0,0 +1,42 @@ +class Solution { + private List[] g; + private boolean[] vis; + private int[] values; + private int maxTime; + private int ans; + + public int maximalPathQuality(int[] values, int[][] edges, int maxTime) { + int n = values.length; + g = new List[n]; + Arrays.setAll(g, k -> new ArrayList<>()); + for (var e : edges) { + int u = e[0], v = e[1], t = e[2]; + g[u].add(new int[] {v, t}); + g[v].add(new int[] {u, t}); + } + vis = new boolean[n]; + vis[0] = true; + this.values = values; + this.maxTime = maxTime; + dfs(0, 0, values[0]); + return ans; + } + + private void dfs(int u, int cost, int value) { + if (u == 0) { + ans = Math.max(ans, value); + } + for (var e : g[u]) { + int v = e[0], t = e[1]; + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(v, cost + t, value); + } else { + vis[v] = true; + dfs(v, cost + t, value + values[v]); + vis[v] = false; + } + } + } + } +} \ No newline at end of file diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.py b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.py new file mode 100644 index 0000000000000..1732fd8afd4fc --- /dev/null +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.py @@ -0,0 +1,27 @@ +class Solution: + def maximalPathQuality( + self, values: List[int], edges: List[List[int]], maxTime: int + ) -> int: + def dfs(u: int, cost: int, value: int): + if u == 0: + nonlocal ans + ans = max(ans, value) + for v, t in g[u]: + if cost + t <= maxTime: + if vis[v]: + dfs(v, cost + t, value) + else: + vis[v] = True + dfs(v, cost + t, value + values[v]) + vis[v] = False + + n = len(values) + g = [[] for _ in range(n)] + for u, v, t in edges: + g[u].append((v, t)) + g[v].append((u, t)) + vis = [False] * n + vis[0] = True + ans = 0 + dfs(0, 0, values[0]) + return ans diff --git a/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.ts b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.ts index 90df5575a8744..4b41f6f15d0b6 100644 --- a/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.ts +++ b/solution/2000-2099/2065.Maximum Path Quality of a Graph/Solution.ts @@ -1,35 +1,29 @@ function maximalPathQuality(values: number[], edges: number[][], maxTime: number): number { const n = values.length; - let g: Array>> = Array.from({ length: n }, v => new Array()); - for (let edge of edges) { - let [u, v, t] = edge; + const g: [number, number][][] = Array.from({ length: n }, () => []); + for (const [u, v, t] of edges) { g[u].push([v, t]); g[v].push([u, t]); } - let visited = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); + vis[0] = true; let ans = 0; - - function dfs(u: number, time: number, value: number): void { - // 索引0为终点 - if (!u) { - ans = Math.max(value, ans); + const dfs = (u: number, cost: number, value: number) => { + if (u === 0) { + ans = Math.max(ans, value); } - for (let [v, dist] of g[u]) { - if (time - dist >= 0) { - if (!visited[v]) { - visited[v] = true; - dfs(v, time - dist, value + values[v]); - visited[v] = false; // 回溯 + for (const [v, t] of g[u]) { + if (cost + t <= maxTime) { + if (vis[v]) { + dfs(v, cost + t, value); } else { - dfs(v, time - dist, value); + vis[v] = true; + dfs(v, cost + t, value + values[v]); + vis[v] = false; } } } - } - - // 索引0为起点 - visited[0] = true; - dfs(0, maxTime, values[0]); - + }; + dfs(0, 0, values[0]); return ans; }