Skip to content

feat: add solutions to lc problem: No.2065 #3183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 186 additions & 23 deletions solution/2000-2099/2065.Maximum Path Quality of a Graph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,46 +100,209 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一: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$ 分别表示节点数和边数。

<!-- tabs:start -->

#### 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<int[]>[] 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<int>& values, vector<vector<int>>& edges, int maxTime) {
int n = values.size();
vector<pair<int, int>> 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<Array<number>>> = 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;
}
```
Expand Down
Loading
Loading