Skip to content

Commit 46c00f0

Browse files
authored
feat: add solutions to lc problem: No.2925 (doocs#1940)
No.2925.Maximum Score After Applying Operations on a Tree
1 parent e5558e5 commit 46c00f0

File tree

8 files changed

+468
-8
lines changed

8 files changed

+468
-8
lines changed

run_format.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,21 @@
44
import re
55
import black
66

7-
suffixes = ["md", "go"]
7+
suffixes = ["md", "py", "java", "c", "cpp", "go", "php", "cs", "rs", "js", "ts", "sql"]
88

9-
code_blocks = ["go"]
9+
code_blocks = [
10+
"python",
11+
"java",
12+
"cpp",
13+
"c",
14+
"go",
15+
"ts",
16+
"js",
17+
"php",
18+
"cs",
19+
"rust",
20+
"sql",
21+
]
1022

1123
functions_to_replace = [
1224
"ABS",

solution/2900-2999/2925.Maximum Score After Applying Operations on a Tree/README.md

+158-3
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,189 @@
6969

7070
<!-- 这里可写通用的实现逻辑 -->
7171

72+
**方法一:树形 DP**
73+
74+
题目实际上是让我们从树的所有节点中选出一些节点,使得这些节点的值之和最大,并且每条从根节点到叶子节点的路径上都有一个点没有被选中。
75+
76+
我们可以使用树形 DP 的方法解决这个问题。
77+
78+
我们设计一个函数 $dfs(i, fa)$,其中 $i$ 表示当前以节点 $i$ 作为子树的根节点,且 $fa$ 表示 $i$ 的父节点,函数返回一个长度为 $2$ 的数组,其中 $[0]$ 表示该子树中所有节点的值之和,而 $[1]$ 表示该子树满足每条路径上都有一个点没有被选中的最大值。
79+
80+
其中 $[0]$ 的值可以直接通过 DFS 累加每个节点的值得到,而 $[1]$ 的值,则需要考虑两种情况,即节点 $i$ 是否被选中。如果被选中,那么节点 $i$ 的每个子树得必须满足每条路径上都有一个点没有被选中;如果没有被选中,那么节点 $i$ 的每个子树可以选取所有节点。我们取这两种情况中的最大值即可。
81+
82+
需要注意的是,叶子节点的 $[1]$ 的值为 $0$,因为叶子节点没有子树,所以不需要考虑每条路径上都有一个点没有被选中的情况。
83+
84+
答案为 $dfs(0, -1)[1]$。
85+
86+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
87+
7288
<!-- tabs:start -->
7389

7490
### **Python3**
7591

7692
<!-- 这里可写当前语言的特殊实现逻辑 -->
7793

7894
```python
79-
95+
class Solution:
96+
def maximumScoreAfterOperations(
97+
self, edges: List[List[int]], values: List[int]
98+
) -> int:
99+
def dfs(i: int, fa: int = -1) -> (int, int):
100+
a = b = 0
101+
leaf = True
102+
for j in g[i]:
103+
if j != fa:
104+
leaf = False
105+
aa, bb = dfs(j, i)
106+
a += aa
107+
b += bb
108+
if leaf:
109+
return values[i], 0
110+
return values[i] + a, max(values[i] + b, a)
111+
112+
g = [[] for _ in range(len(values))]
113+
for a, b in edges:
114+
g[a].append(b)
115+
g[b].append(a)
116+
return dfs(0)[1]
80117
```
81118

82119
### **Java**
83120

84121
<!-- 这里可写当前语言的特殊实现逻辑 -->
85122

86123
```java
87-
124+
class Solution {
125+
private List<Integer>[] g;
126+
private int[] values;
127+
128+
public long maximumScoreAfterOperations(int[][] edges, int[] values) {
129+
int n = values.length;
130+
g = new List[n];
131+
this.values = values;
132+
Arrays.setAll(g, k -> new ArrayList<>());
133+
for (var e : edges) {
134+
int a = e[0], b = e[1];
135+
g[a].add(b);
136+
g[b].add(a);
137+
}
138+
return dfs(0, -1)[1];
139+
}
140+
141+
private long[] dfs(int i, int fa) {
142+
long a = 0, b = 0;
143+
boolean leaf = true;
144+
for (int j : g[i]) {
145+
if (j != fa) {
146+
leaf = false;
147+
var t = dfs(j, i);
148+
a += t[0];
149+
b += t[1];
150+
}
151+
}
152+
if (leaf) {
153+
return new long[] {values[i], 0};
154+
}
155+
return new long[] {values[i] + a, Math.max(values[i] + b, a)};
156+
}
157+
}
88158
```
89159

90160
### **C++**
91161

92162
```cpp
93-
163+
class Solution {
164+
public:
165+
long long maximumScoreAfterOperations(vector<vector<int>>& edges, vector<int>& values) {
166+
int n = values.size();
167+
vector<int> g[n];
168+
for (auto& e : edges) {
169+
int a = e[0], b = e[1];
170+
g[a].emplace_back(b);
171+
g[b].emplace_back(a);
172+
}
173+
using ll = long long;
174+
function<pair<ll, ll>(int, int)> dfs = [&](int i, int fa) -> pair<ll, ll> {
175+
ll a = 0, b = 0;
176+
bool leaf = true;
177+
for (int j : g[i]) {
178+
if (j != fa) {
179+
auto [aa, bb] = dfs(j, i);
180+
a += aa;
181+
b += bb;
182+
leaf = false;
183+
}
184+
}
185+
if (leaf) {
186+
return {values[i], 0LL};
187+
}
188+
return {values[i] + a, max(values[i] + b, a)};
189+
};
190+
auto [_, b] = dfs(0, -1);
191+
return b;
192+
}
193+
};
94194
```
95195
96196
### **Go**
97197
98198
```go
199+
func maximumScoreAfterOperations(edges [][]int, values []int) int64 {
200+
g := make([][]int, len(values))
201+
for _, e := range edges {
202+
a, b := e[0], e[1]
203+
g[a] = append(g[a], b)
204+
g[b] = append(g[b], a)
205+
}
206+
var dfs func(int, int) (int64, int64)
207+
dfs = func(i, fa int) (int64, int64) {
208+
a, b := int64(0), int64(0)
209+
leaf := true
210+
for _, j := range g[i] {
211+
if j != fa {
212+
leaf = false
213+
aa, bb := dfs(j, i)
214+
a += aa
215+
b += bb
216+
}
217+
}
218+
if leaf {
219+
return int64(values[i]), int64(0)
220+
}
221+
return int64(values[i]) + a, max(int64(values[i])+b, a)
222+
}
223+
_, b := dfs(0, -1)
224+
return b
225+
}
226+
```
99227

228+
### **TypeScript**
229+
230+
```ts
231+
function maximumScoreAfterOperations(edges: number[][], values: number[]): number {
232+
const g: number[][] = Array.from({ length: values.length }, () => []);
233+
for (const [a, b] of edges) {
234+
g[a].push(b);
235+
g[b].push(a);
236+
}
237+
const dfs = (i: number, fa: number): [number, number] => {
238+
let [a, b] = [0, 0];
239+
let leaf = true;
240+
for (const j of g[i]) {
241+
if (j !== fa) {
242+
const [aa, bb] = dfs(j, i);
243+
a += aa;
244+
b += bb;
245+
leaf = false;
246+
}
247+
}
248+
if (leaf) {
249+
return [values[i], 0];
250+
}
251+
return [values[i] + a, Math.max(values[i] + b, a)];
252+
};
253+
return dfs(0, -1)[1];
254+
}
100255
```
101256

102257
### **...**

0 commit comments

Comments
 (0)