Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 46c00f0

Browse files
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‎

Lines changed: 14 additions & 2 deletions
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‎

Lines changed: 158 additions & 3 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /