Skip to content

Commit b6468cf

Browse files
committed
feat: add solutions to lc problem: No.3607
1 parent 2b4d71c commit b6468cf

File tree

5 files changed

+581
-8
lines changed

5 files changed

+581
-8
lines changed

solution/3600-3699/3607.Power Grid Maintenance/README.md

Lines changed: 199 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,26 +108,221 @@ tags:
108108

109109
<!-- solution:start -->
110110

111-
### 方法一
111+
### 方法一:并查集 + 有序集合
112+
113+
我们可以使用并查集(Union-Find)来维护电站之间的连接关系,从而确定每个电站所属的电网。对于每个电网,我们使用有序集合(如 Python 中的 `SortedList`、Java 中的 `TreeSet` 或 C++ 中的 `std::set`)来存储该电网中所有在线的电站编号,以便能够高效地查询和删除电站。
114+
115+
具体步骤如下:
116+
117+
1. 初始化并查集,处理所有连接关系,将连接的电站合并到同一个集合中。
118+
2. 为每个电网创建一个有序集合,初始时将所有电站编号加入对应电网的集合中。
119+
3. 遍历查询列表:
120+
- 对于查询 $[1, x]$,首先找到电站 $x$ 所属的电网根节点,然后检查该电网的有序集合:
121+
- 如果电站 $x$ 在线(存在于集合中),则返回 $x$。
122+
- 否则,返回集合中的最小编号电站(如果集合非空),否则返回 -1。
123+
- 对于查询 $[2, x]$,找到电站 $x$ 所属的电网根节点,并将电站 $x$ 从该电网的有序集合中删除,表示该电站离线。
124+
4. 最后,返回所有类型为 $[1, x]$ 的查询结果。
125+
126+
时间复杂度 $O((c + n + q) \log c)$,空间复杂度 $O(c)$。其中 $c$ 是电站数量,而 $n$ 和 $q$ 分别是连接数量和查询数量。
112127

113128
<!-- tabs:start -->
114129

115130
#### Python3
116131

117132
```python
118-
133+
class UnionFind:
134+
def __init__(self, n):
135+
self.p = list(range(n))
136+
self.size = [1] * n
137+
138+
def find(self, x):
139+
if self.p[x] != x:
140+
self.p[x] = self.find(self.p[x])
141+
return self.p[x]
142+
143+
def union(self, a, b):
144+
pa, pb = self.find(a), self.find(b)
145+
if pa == pb:
146+
return False
147+
if self.size[pa] > self.size[pb]:
148+
self.p[pb] = pa
149+
self.size[pa] += self.size[pb]
150+
else:
151+
self.p[pa] = pb
152+
self.size[pb] += self.size[pa]
153+
return True
154+
155+
156+
class Solution:
157+
def processQueries(
158+
self, c: int, connections: List[List[int]], queries: List[List[int]]
159+
) -> List[int]:
160+
uf = UnionFind(c + 1)
161+
for u, v in connections:
162+
uf.union(u, v)
163+
st = [SortedList() for _ in range(c + 1)]
164+
for i in range(1, c + 1):
165+
st[uf.find(i)].add(i)
166+
ans = []
167+
for a, x in queries:
168+
root = uf.find(x)
169+
if a == 1:
170+
if x in st[root]:
171+
ans.append(x)
172+
elif len(st[root]):
173+
ans.append(st[root][0])
174+
else:
175+
ans.append(-1)
176+
else:
177+
st[root].discard(x)
178+
return ans
119179
```
120180

121181
#### Java
122182

123183
```java
124-
184+
class UnionFind {
185+
private final int[] p;
186+
private final int[] size;
187+
188+
public UnionFind(int n) {
189+
p = new int[n];
190+
size = new int[n];
191+
for (int i = 0; i < n; ++i) {
192+
p[i] = i;
193+
size[i] = 1;
194+
}
195+
}
196+
197+
public int find(int x) {
198+
if (p[x] != x) {
199+
p[x] = find(p[x]);
200+
}
201+
return p[x];
202+
}
203+
204+
public boolean union(int a, int b) {
205+
int pa = find(a), pb = find(b);
206+
if (pa == pb) {
207+
return false;
208+
}
209+
if (size[pa] > size[pb]) {
210+
p[pb] = pa;
211+
size[pa] += size[pb];
212+
} else {
213+
p[pa] = pb;
214+
size[pb] += size[pa];
215+
}
216+
return true;
217+
}
218+
}
219+
220+
class Solution {
221+
public int[] processQueries(int c, int[][] connections, int[][] queries) {
222+
UnionFind uf = new UnionFind(c + 1);
223+
for (int[] e : connections) {
224+
uf.union(e[0], e[1]);
225+
}
226+
227+
TreeSet<Integer>[] st = new TreeSet[c + 1];
228+
Arrays.setAll(st, k -> new TreeSet<>());
229+
for (int i = 1; i <= c; i++) {
230+
int root = uf.find(i);
231+
st[root].add(i);
232+
}
233+
234+
List<Integer> ans = new ArrayList<>();
235+
for (int[] q : queries) {
236+
int a = q[0], x = q[1];
237+
int root = uf.find(x);
238+
239+
if (a == 1) {
240+
if (st[root].contains(x)) {
241+
ans.add(x);
242+
} else if (!st[root].isEmpty()) {
243+
ans.add(st[root].first());
244+
} else {
245+
ans.add(-1);
246+
}
247+
} else {
248+
st[root].remove(x);
249+
}
250+
}
251+
252+
return ans.stream().mapToInt(Integer::intValue).toArray();
253+
}
254+
}
125255
```
126256

127257
#### C++
128258

129259
```cpp
130-
260+
class UnionFind {
261+
public:
262+
UnionFind(int n) {
263+
p = vector<int>(n);
264+
size = vector<int>(n, 1);
265+
iota(p.begin(), p.end(), 0);
266+
}
267+
268+
bool unite(int a, int b) {
269+
int pa = find(a), pb = find(b);
270+
if (pa == pb) {
271+
return false;
272+
}
273+
if (size[pa] > size[pb]) {
274+
p[pb] = pa;
275+
size[pa] += size[pb];
276+
} else {
277+
p[pa] = pb;
278+
size[pb] += size[pa];
279+
}
280+
return true;
281+
}
282+
283+
int find(int x) {
284+
if (p[x] != x) {
285+
p[x] = find(p[x]);
286+
}
287+
return p[x];
288+
}
289+
290+
private:
291+
vector<int> p, size;
292+
};
293+
294+
class Solution {
295+
public:
296+
vector<int> processQueries(int c, vector<vector<int>>& connections, vector<vector<int>>& queries) {
297+
UnionFind uf(c + 1);
298+
for (auto& e : connections) {
299+
uf.unite(e[0], e[1]);
300+
}
301+
302+
vector<set<int>> st(c + 1);
303+
for (int i = 1; i <= c; i++) {
304+
st[uf.find(i)].insert(i);
305+
}
306+
307+
vector<int> ans;
308+
for (auto& q : queries) {
309+
int a = q[0], x = q[1];
310+
int root = uf.find(x);
311+
if (a == 1) {
312+
if (st[root].count(x)) {
313+
ans.push_back(x);
314+
} else if (!st[root].empty()) {
315+
ans.push_back(*st[root].begin());
316+
} else {
317+
ans.push_back(-1);
318+
}
319+
} else {
320+
st[root].erase(x);
321+
}
322+
}
323+
return ans;
324+
}
325+
};
131326
```
132327

133328
#### Go

0 commit comments

Comments
 (0)