63
63
64
64
<!-- 这里可写通用的实现逻辑 -->
65
65
66
- 并查集。
66
+ 并查集。对于本题,构造两个并查集。同时操作两个并查集 ufa, ufb,遵从优先添加公共边的策略,即:优先添加 ` type = 3 ` 的边。添加的过程中,若两点已连通,则累加多余的边 ans。
67
+
68
+ 然后遍历 ` type = 1 ` 的边添加到 ufa 中,而 ` type = 2 ` 的边则添加到 ufb 中。此过程同样判断两点是否已连通,若是,则累加多余的边 ans。
69
+
70
+ 最后判断两个并查集是否都只有一个连通分量,若是,返回 ans,否则返回 -1。
71
+
72
+ 以下是并查集的几个常用模板。
67
73
68
74
模板 1——朴素并查集:
69
75
@@ -116,12 +122,6 @@ p[find(a)] = find(b)
116
122
d[find(a)] = distance
117
123
```
118
124
119
- 对于本题,构造两个并查集。同时操作两个并查集 ufa, ufb,优先添加 ` type = 3 ` 的边,添加的过程中,若两点已连通,则累加多余的边 res。
120
-
121
- 然后遍历 ` type = 1 ` 的边添加到 ufa 中,而 ` type = 2 ` 的边则添加到 ufb 中。此过程同样判断两点是否已连通,若是,则累加多余的边 res。
122
-
123
- 最后判断两个并查集是否都只有一个连通分量,若是,返回 res,否则返回 -1。
124
-
125
125
<!-- tabs:start -->
126
126
127
127
### ** Python3**
@@ -134,37 +134,33 @@ class UnionFind:
134
134
self .p = list (range (n))
135
135
self .n = n
136
136
137
- def union (self , a , b ) -> bool :
137
+ def union (self , a , b ):
138
138
pa, pb = self .find(a - 1 ), self .find(b - 1 )
139
139
if pa == pb:
140
140
return False
141
141
self .p[pa] = pb
142
142
self .n -= 1
143
143
return True
144
144
145
- def find (self , x ) -> int :
145
+ def find (self , x ):
146
146
if self .p[x] != x:
147
147
self .p[x] = self .find(self .p[x])
148
148
return self .p[x]
149
149
150
+
150
151
class Solution :
151
152
def maxNumEdgesToRemove (self , n : int , edges : List[List[int ]]) -> int :
152
153
ufa, ufb = UnionFind(n), UnionFind(n)
153
- res = 0
154
+ ans = 0
154
155
for t, u, v in edges:
155
156
if t == 3 :
156
- if not ufa.union(u, v):
157
- res += 1
158
- else :
157
+ if ufa.union(u, v):
159
158
ufb.union(u, v)
160
- for t, u, v in edges:
161
- if t == 1 :
162
- if not ufa.union(u, v):
163
- res += 1
164
- elif t == 2 :
165
- if not ufb.union(u, v):
166
- res += 1
167
- return res if ufa.n == 1 and ufb.n == 1 else - 1
159
+ else :
160
+ ans += 1
161
+ ans += sum ((t == 1 and not ufa.union(u, v))
162
+ or (t == 2 and not ufb.union(u, v)) for t, u, v in edges)
163
+ return ans if ufa.n == 1 and ufb.n == 1 else - 1
168
164
```
169
165
170
166
### ** Java**
@@ -176,28 +172,22 @@ class Solution {
176
172
public int maxNumEdgesToRemove (int n , int [][] edges ) {
177
173
UnionFind ufa = new UnionFind (n);
178
174
UnionFind ufb = new UnionFind (n);
179
- int res = 0 ;
175
+ int ans = 0 ;
180
176
for (int [] e : edges) {
181
177
if (e[0 ] == 3 ) {
182
- if (! ufa. union(e[1 ], e[2 ])) {
183
- ++ res;
184
- } else {
178
+ if (ufa. union(e[1 ], e[2 ])) {
185
179
ufb. union(e[1 ], e[2 ]);
180
+ } else {
181
+ ++ ans;
186
182
}
187
183
}
188
184
}
189
185
for (int [] e : edges) {
190
- if (e[0 ] == 1 ) {
191
- if (! ufa. union(e[1 ], e[2 ])) {
192
- ++ res;
193
- }
194
- } else if (e[0 ] == 2 ) {
195
- if (! ufb. union(e[1 ], e[2 ])) {
196
- ++ res;
197
- }
186
+ if ((e[0 ] == 1 && ! ufa. union(e[1 ], e[2 ])) || (e[0 ] == 2 && ! ufb. union(e[1 ], e[2 ]))) {
187
+ ++ ans;
198
188
}
199
189
}
200
- return ufa. n == 1 && ufb. n == 1 ? res : - 1 ;
190
+ return ufa. n == 1 && ufb. n == 1 ? ans : - 1 ;
201
191
}
202
192
}
203
193
@@ -214,7 +204,8 @@ class UnionFind {
214
204
}
215
205
216
206
public boolean union (int a , int b ) {
217
- int pa = find(a - 1 ), pb = find(b - 1 );
207
+ int pa = find(a - 1 );
208
+ int pb = find(b - 1 );
218
209
if (pa == pb) {
219
210
return false ;
220
211
}
@@ -246,16 +237,14 @@ public:
246
237
247
238
bool unite (int a, int b) {
248
239
int pa = find(a - 1), pb = find(b - 1);
249
- if (pa == pb)
250
- return false;
240
+ if (pa == pb) return false;
251
241
p[ pa] = pb;
252
242
--n;
253
243
return true;
254
244
}
255
245
256
246
int find(int x) {
257
- if (p[x] != x)
258
- p[x] = find(p[x]);
247
+ if (p[x] != x) p[x] = find(p[x]);
259
248
return p[x];
260
249
}
261
250
};
@@ -264,27 +253,19 @@ class Solution {
264
253
public:
265
254
int maxNumEdgesToRemove(int n, vector<vector<int >>& edges) {
266
255
UnionFind ufa(n), ufb(n);
267
- int res = 0;
268
- for (auto e : edges)
256
+ int ans = 0;
257
+ for (auto& e : edges)
269
258
{
270
259
if (e[ 0] == 3)
271
260
{
272
- if (! ufa.unite(e[ 1] , e[ 2] )) ++res ;
273
- else ufb.unite(e [ 1 ] , e [ 2 ] ) ;
261
+ if (ufa.unite(e[ 1] , e[ 2] )) ufb.unite(e [ 1 ] , e [ 2 ] ) ;
262
+ else ++ans ;
274
263
}
275
264
}
276
- for (auto e : edges)
277
- {
278
- if (e[ 0] == 1)
279
- {
280
- if (!ufa.unite(e[ 1] , e[ 2] )) ++res;
281
- }
282
- else if (e[ 0] == 2)
283
- {
284
- if (!ufb.unite(e[ 1] , e[ 2] )) ++res;
285
- }
286
- }
287
- return ufa.n == 1 && ufb.n == 1 ? res : -1;
265
+ for (auto& e : edges)
266
+ if ((e[ 0] == 1 && !ufa.unite(e[ 1] , e[ 2] )) || (e[ 0] == 2 && !ufb.unite(e[ 1] , e[ 2] )))
267
+ ++ans;
268
+ return ufa.n == 1 && ufb.n == 1 ? ans : -1;
288
269
}
289
270
};
290
271
```
@@ -324,29 +305,23 @@ func (uf *unionFind) union(a, b int) bool {
324
305
325
306
func maxNumEdgesToRemove(n int, edges [][]int) int {
326
307
ufa, ufb := newUnionFind(n), newUnionFind(n)
327
- res := 0
308
+ ans := 0
328
309
for _, e := range edges {
329
310
if e[0] == 3 {
330
- if !ufa.union(e[1], e[2]) {
331
- res++
332
- } else {
311
+ if ufa.union(e[1], e[2]) {
333
312
ufb.union(e[1], e[2])
313
+ } else {
314
+ ans++
334
315
}
335
316
}
336
317
}
337
318
for _, e := range edges {
338
- if e[0] == 1 {
339
- if !ufa.union(e[1], e[2]) {
340
- res++
341
- }
342
- } else if e[0] == 2 {
343
- if !ufb.union(e[1], e[2]) {
344
- res++
345
- }
319
+ if (e[0] == 1 && !ufa.union(e[1], e[2])) || (e[0] == 2 && !ufb.union(e[1], e[2])) {
320
+ ans++
346
321
}
347
322
}
348
323
if ufa.n == 1 && ufb.n == 1 {
349
- return res
324
+ return ans
350
325
}
351
326
return -1
352
327
}
0 commit comments