Skip to content

Commit 01bb9ea

Browse files
committed
feat: add solutions to lc problem: No.2378
No.2378.Choose Edges to Maximize Score in a Tree
1 parent 4dbdea4 commit 01bb9ea

File tree

6 files changed

+140
-159
lines changed

6 files changed

+140
-159
lines changed

solution/2300-2399/2378.Choose Edges to Maximize Score in a Tree/README.md

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@
6969

7070
**方法一:树形 DP**
7171

72+
我们设计一个函数 $dfs(i)$,表示以节点 $i$ 为根的子树中,选择一些边,使得所选的两条边都不相邻,所选边的权值之和最大。该函数返回了两个值 $(a, b)$,第一个值 $a$ 表示当前节点 $i$ 与其父节点之间的边被选中时,所选边的权值之和;第二个值 $b$ 表示当前节点 $i$ 与其父节点之间的边不被选中时,所选边的权值之和。
73+
74+
我们可以发现,对于当前节点 $i$:
75+
76+
- 如果 $i$ 与父节点的边被选择,则它与子节点的所有边都不能被选择,那么当前节点的 $a$ 值就是其所有子节点的 $b$ 值之和;
77+
- 如果 $i$ 与父节点的边没被选择,那么可以选择它与子节点的最多一条边,那么当前节点的 $b$ 值就是其选中的子节点的 $a$ 值与未选中的子节点的 $b$ 值之和,再加上 $i$ 与选中的子节点之间的边的权值。
78+
79+
我们调用 $dfs(0)$ 函数,返回的第二个值即为答案,即当前根节点不与父节点之间的边被选中时,所选边的权值之和。
80+
81+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
82+
7283
<!-- tabs:start -->
7384

7485
### **Python3**
@@ -79,20 +90,19 @@
7990
class Solution:
8091
def maxScore(self, edges: List[List[int]]) -> int:
8192
def dfs(i):
82-
a = b = 0
83-
t = 0
84-
for j in g[i]:
93+
a = b = t = 0
94+
for j, w in g[i]:
8595
x, y = dfs(j)
8696
a += y
8797
b += y
88-
t = max(t, x - y + g[i][j])
98+
t = max(t, x - y + w)
8999
b += t
90100
return a, b
91101

92-
g = defaultdict(lambda: defaultdict(lambda: -inf))
102+
g = defaultdict(list)
93103
for i, (p, w) in enumerate(edges[1:], 1):
94-
g[p][i] = w
95-
return max(dfs(0))
104+
g[p].append((i, w))
105+
return dfs(0)[1]
96106
```
97107

98108
### **Java**
@@ -101,67 +111,61 @@ class Solution:
101111

102112
```java
103113
class Solution {
104-
private Map<Integer, Integer>[] g;
114+
private List<int[]>[] g;
105115

106116
public long maxScore(int[][] edges) {
107117
int n = edges.length;
108-
g = new Map[n + 1];
109-
for (int i = 0; i < n + 1; ++i) {
110-
g[i] = new HashMap<>();
111-
}
118+
g = new List[n];
119+
Arrays.setAll(g, k -> new ArrayList<>());
112120
for (int i = 1; i < n; ++i) {
113121
int p = edges[i][0], w = edges[i][1];
114-
g[p].put(i, w);
122+
g[p].add(new int[]{i, w});
115123
}
116124
return dfs(0)[1];
117125
}
118126

119127
private long[] dfs(int i) {
120-
long a = 0, b = 0;
121-
long t = 0;
122-
for (int j : g[i].keySet()) {
128+
long a = 0, b = 0, t = 0;
129+
for (int[] nxt : g[i]) {
130+
int j = nxt[0], w = nxt[1];
123131
long[] s = dfs(j);
124132
a += s[1];
125133
b += s[1];
126-
t = Math.max(t, s[0] - s[1] + g[i].get(j));
134+
t = Math.max(t, s[0] - s[1] + w);
127135
}
128136
b += t;
129-
return new long[] {a, b};
137+
return new long[]{a, b};
130138
}
131139
}
132140
```
133141

134142
### **C++**
135143

136144
```cpp
137-
using ll = long long;
138-
139145
class Solution {
140146
public:
141-
vector<unordered_map<int, int>> g;
142-
143147
long long maxScore(vector<vector<int>>& edges) {
144148
int n = edges.size();
145-
g.resize(n + 1);
149+
vector<vector<pair<int, int>>> g(n);
146150
for (int i = 1; i < n; ++i) {
147151
int p = edges[i][0], w = edges[i][1];
148-
g[p][i] = w;
152+
g[p].emplace_back(i, w);
149153
}
154+
using ll = long long;
155+
using pll = pair<ll, ll>;
156+
function<pll(int)> dfs = [&](int i) -> pll {
157+
ll a = 0, b = 0, t = 0;
158+
for (auto& [j, w] : g[i]) {
159+
auto [x, y] = dfs(j);
160+
a += y;
161+
b += y;
162+
t = max(t, x - y + w);
163+
}
164+
b += t;
165+
return make_pair(a, b);
166+
};
150167
return dfs(0).second;
151168
}
152-
153-
pair<ll, ll> dfs(int i) {
154-
ll a = 0, b = 0;
155-
ll s = 0;
156-
for (auto& [j, v] : g[i]) {
157-
auto t = dfs(j);
158-
a += t.second;
159-
b += t.second;
160-
s = max(s, t.first - t.second + v);
161-
}
162-
b += s;
163-
return {a, b};
164-
}
165169
};
166170
```
167171
@@ -170,26 +174,23 @@ public:
170174
```go
171175
func maxScore(edges [][]int) int64 {
172176
n := len(edges)
173-
g := make([]map[int]int, n+1)
174-
for i := range g {
175-
g[i] = make(map[int]int)
176-
}
177+
g := make([][][2]int, n)
177178
for i := 1; i < n; i++ {
178179
p, w := edges[i][0], edges[i][1]
179-
g[p][i] = w
180+
g[p] = append(g[p], [2]int{i, w})
180181
}
181-
var dfs func(i int) []int
182-
dfs = func(i int) []int {
183-
a, b := 0, 0
184-
s := 0
185-
for j, v := range g[i] {
186-
t := dfs(j)
187-
a += t[1]
188-
b += t[1]
189-
s = max(s, t[0]-t[1]+v)
182+
var dfs func(int) [2]int
183+
dfs = func(i int) [2]int {
184+
var a, b, t int
185+
for _, e := range g[i] {
186+
j, w := e[0], e[1]
187+
s := dfs(j)
188+
a += s[1]
189+
b += s[1]
190+
t = max(t, s[0]-s[1]+w)
190191
}
191-
b += s
192-
return []int{a, b}
192+
b += t
193+
return [2]int{a, b}
193194
}
194195
return int64(dfs(0)[1])
195196
}

solution/2300-2399/2378.Choose Edges to Maximize Score in a Tree/README_EN.md

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -67,87 +67,80 @@ Note that we cannot choose more than one edge because all edges are adjacent to
6767
class Solution:
6868
def maxScore(self, edges: List[List[int]]) -> int:
6969
def dfs(i):
70-
a = b = 0
71-
t = 0
72-
for j in g[i]:
70+
a = b = t = 0
71+
for j, w in g[i]:
7372
x, y = dfs(j)
7473
a += y
7574
b += y
76-
t = max(t, x - y + g[i][j])
75+
t = max(t, x - y + w)
7776
b += t
7877
return a, b
7978

80-
g = defaultdict(lambda: defaultdict(lambda: -inf))
79+
g = defaultdict(list)
8180
for i, (p, w) in enumerate(edges[1:], 1):
82-
g[p][i] = w
83-
return max(dfs(0))
81+
g[p].append((i, w))
82+
return dfs(0)[1]
8483
```
8584

8685
### **Java**
8786

8887
```java
8988
class Solution {
90-
private Map<Integer, Integer>[] g;
89+
private List<int[]>[] g;
9190

9291
public long maxScore(int[][] edges) {
9392
int n = edges.length;
94-
g = new Map[n + 1];
95-
for (int i = 0; i < n + 1; ++i) {
96-
g[i] = new HashMap<>();
97-
}
93+
g = new List[n];
94+
Arrays.setAll(g, k -> new ArrayList<>());
9895
for (int i = 1; i < n; ++i) {
9996
int p = edges[i][0], w = edges[i][1];
100-
g[p].put(i, w);
97+
g[p].add(new int[]{i, w});
10198
}
10299
return dfs(0)[1];
103100
}
104101

105102
private long[] dfs(int i) {
106-
long a = 0, b = 0;
107-
long t = 0;
108-
for (int j : g[i].keySet()) {
103+
long a = 0, b = 0, t = 0;
104+
for (int[] nxt : g[i]) {
105+
int j = nxt[0], w = nxt[1];
109106
long[] s = dfs(j);
110107
a += s[1];
111108
b += s[1];
112-
t = Math.max(t, s[0] - s[1] + g[i].get(j));
109+
t = Math.max(t, s[0] - s[1] + w);
113110
}
114111
b += t;
115-
return new long[] {a, b};
112+
return new long[]{a, b};
116113
}
117114
}
118115
```
119116

120117
### **C++**
121118

122119
```cpp
123-
using ll = long long;
124-
125120
class Solution {
126121
public:
127-
vector<unordered_map<int, int>> g;
128-
129122
long long maxScore(vector<vector<int>>& edges) {
130123
int n = edges.size();
131-
g.resize(n + 1);
124+
vector<vector<pair<int, int>>> g(n);
132125
for (int i = 1; i < n; ++i) {
133126
int p = edges[i][0], w = edges[i][1];
134-
g[p][i] = w;
127+
g[p].emplace_back(i, w);
135128
}
129+
using ll = long long;
130+
using pll = pair<ll, ll>;
131+
function<pll(int)> dfs = [&](int i) -> pll {
132+
ll a = 0, b = 0, t = 0;
133+
for (auto& [j, w] : g[i]) {
134+
auto [x, y] = dfs(j);
135+
a += y;
136+
b += y;
137+
t = max(t, x - y + w);
138+
}
139+
b += t;
140+
return make_pair(a, b);
141+
};
136142
return dfs(0).second;
137143
}
138-
139-
pair<ll, ll> dfs(int i) {
140-
ll a = 0, b = 0;
141-
ll s = 0;
142-
for (auto& [j, v] : g[i]) {
143-
auto t = dfs(j);
144-
a += t.second;
145-
b += t.second;
146-
s = max(s, t.first - t.second + v);
147-
}
148-
b += s;
149-
return {a, b};
150-
}
151144
};
152145
```
153146
@@ -156,26 +149,23 @@ public:
156149
```go
157150
func maxScore(edges [][]int) int64 {
158151
n := len(edges)
159-
g := make([]map[int]int, n+1)
160-
for i := range g {
161-
g[i] = make(map[int]int)
162-
}
152+
g := make([][][2]int, n)
163153
for i := 1; i < n; i++ {
164154
p, w := edges[i][0], edges[i][1]
165-
g[p][i] = w
155+
g[p] = append(g[p], [2]int{i, w})
166156
}
167-
var dfs func(i int) []int
168-
dfs = func(i int) []int {
169-
a, b := 0, 0
170-
s := 0
171-
for j, v := range g[i] {
172-
t := dfs(j)
173-
a += t[1]
174-
b += t[1]
175-
s = max(s, t[0]-t[1]+v)
157+
var dfs func(int) [2]int
158+
dfs = func(i int) [2]int {
159+
var a, b, t int
160+
for _, e := range g[i] {
161+
j, w := e[0], e[1]
162+
s := dfs(j)
163+
a += s[1]
164+
b += s[1]
165+
t = max(t, s[0]-s[1]+w)
176166
}
177-
b += s
178-
return []int{a, b}
167+
b += t
168+
return [2]int{a, b}
179169
}
180170
return int64(dfs(0)[1])
181171
}
Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,25 @@
1-
using ll = long long;
2-
31
class Solution {
42
public:
5-
vector<unordered_map<int, int>> g;
6-
73
long long maxScore(vector<vector<int>>& edges) {
84
int n = edges.size();
9-
g.resize(n + 1);
5+
vector<vector<pair<int, int>>> g(n);
106
for (int i = 1; i < n; ++i) {
117
int p = edges[i][0], w = edges[i][1];
12-
g[p][i] = w;
8+
g[p].emplace_back(i, w);
139
}
10+
using ll = long long;
11+
using pll = pair<ll, ll>;
12+
function<pll(int)> dfs = [&](int i) -> pll {
13+
ll a = 0, b = 0, t = 0;
14+
for (auto& [j, w] : g[i]) {
15+
auto [x, y] = dfs(j);
16+
a += y;
17+
b += y;
18+
t = max(t, x - y + w);
19+
}
20+
b += t;
21+
return make_pair(a, b);
22+
};
1423
return dfs(0).second;
1524
}
16-
17-
pair<ll, ll> dfs(int i) {
18-
ll a = 0, b = 0;
19-
ll s = 0;
20-
for (auto& [j, v] : g[i]) {
21-
auto t = dfs(j);
22-
a += t.second;
23-
b += t.second;
24-
s = max(s, t.first - t.second + v);
25-
}
26-
b += s;
27-
return {a, b};
28-
}
2925
};

0 commit comments

Comments
 (0)