
2025-12-18:电网维护。用go语言,有 c 个电站,编号从 1 到 c。它们之间通过 n 条无向电缆相连,connections 数组中每个元素 [u, v] 表示电站 u 和 v 之间有连接。通过这些连接能够互相到达的一组电站构成一个“电网”(连通分量)。
起初所有电站都是在线(正常工作)的。随后会有一系列操作,记录在 queries 数组中,每条操作有两种形式:
需要按 queries 中的顺序处理操作,并将所有类型为 [1, x] 的查询的返回结果汇总成一个数组输出。注意:电缆连接关系在整个过程中不变,节点即便离线也仍属于原来的连通分量,下线操作不会改变连通结构。
1 <= c <= 100000。
0 <= n == connections.length <= min(100000, c * (c - 1) / 2)。
connections[i].length == 2。
1 <= ui, vi <= c。
ui != vi。
1 <= queries.length <= 2 * 100000。
queries[i].length == 2。
queries[i][0] 为 1 或 2。
1 <= queries[i][1] <= c。
输入: c = 5, connections = [[1,2],[2,3],[3,4],[4,5]], queries = [[1,3],[2,1],[1,1],[2,2],[1,2]]。
输出: [3,2,3]。
解释:

在这里插入图片描述
最初,所有电站 {1, 2, 3, 4, 5} 都在线,并组成一个电网。
查询 [1,3]:电站 3 在线,因此维护检查由电站 3 自行解决。
查询 [2,1]:电站 1 离线。剩余在线电站为 {2, 3, 4, 5}。
查询 [1,1]:电站 1 离线,因此检查由电网中编号最小的在线电站解决,即电站 2。
查询 [2,2]:电站 2 离线。剩余在线电站为 {3, 4, 5}。
查询 [1,2]:电站 2 离线,因此检查由电网中编号最小的在线电站解决,即电站 3。
题目来自力扣3607。
首先根据输入的电缆连接关系 connections 构建一个无向图。使用邻接表来存储这个图,其中 graph[i] 是一个切片,保存了所有与电站 i 直接相连的电站编号。同时,初始化一个 vertices 切片,用于记录每个电站的详细信息,包括其所属的电网(连通分量)ID以及是否处于离线状态。初始时,所有电站的 powerGridId 设为 -1(表示未分配),offline 设为 false(表示在线)。
接下来,需要找出图中所有的连通分量(即“电网”)。代码采用深度优先搜索(DFS)的方式进行遍历:
然后,按顺序处理查询数组 queries 中的每一个操作:
op == 2):x,将其 offline 标志设置为 true。x 虽然离线了,但它仍然属于原来的连通分量,图的连接结构没有改变。代码中并没有在此时从堆中删除 x,这是一种延迟删除策略。op == 1):x 的当前状态。如果 x 在线,那么结果就是 x 本身。x 已离线,则需要从其所属的连通分量对应的最小堆中找出编号最小的在线电站。heap.Pop)。graph 需要 O(c + n) 的空间。vertices 数组需要 O(c) 的空间。.
package main
import (
"container/heap"
"fmt"
)
func processQueries(c int, connections [][]int, queries [][]int) []int {
graph := make([][]int, c+1)
vertices := make([]Vertex, c+1)
for i := 0; i <= c; i++ {
graph[i] = make([]int, 0)
vertices[i] = Vertex{vertexId: i, powerGridId: -1}
}
for _, conn := range connections {
u, v := conn[0], conn[1]
graph[u] = append(graph[u], v)
graph[v] = append(graph[v], u)
}
powerGrids := make([]*IntHeap, 0)
for i, powerGridId := 1, 0; i <= c; i++ {
v := &vertices[i]
if v.powerGridId == -1 {
powerGrid := &IntHeap{}
heap.Init(powerGrid)
traverse(v, powerGridId, powerGrid, graph, vertices)
powerGrids = append(powerGrids, powerGrid)
powerGridId++
}
}
ans := make([]int, 0)
for _, q := range queries {
op, x := q[0], q[1]
if op == 1 {
if !vertices[x].offline {
ans = append(ans, x)
} else {
powerGrid := powerGrids[vertices[x].powerGridId]
for powerGrid.Len() > 0 && vertices[(*powerGrid)[0]].offline {
heap.Pop(powerGrid)
}
if powerGrid.Len() > 0 {
ans = append(ans, (*powerGrid)[0])
} else {
ans = append(ans, -1)
}
}
} elseif op == 2 {
vertices[x].offline = true
}
}
return ans
}
func traverse(u *Vertex, powerGridId int, powerGrid *IntHeap, graph [][]int, vertices []Vertex) {
u.powerGridId = powerGridId
heap.Push(powerGrid, u.vertexId)
for _, vid := range graph[u.vertexId] {
v := &vertices[vid]
if v.powerGridId == -1 {
traverse(v, powerGridId, powerGrid, graph, vertices)
}
}
}
type Vertex struct {
vertexId int
offline bool
powerGridId int
}
type IntHeap []int
func (h IntHeap) Len() int { returnlen(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *IntHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func main() {
c := 5
connections := [][]int{{1, 2}, {2, 3}, {3, 4}, {4, 5}}
queries := [][]int{{1, 3}, {2, 1}, {1, 1}, {2, 2}, {1, 2}}
result := processQueries(c, connections, queries)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
import heapq
from typing import List
def processQueries(c: int, connections: List[List[int]], queries: List[List[int]]) -> List[int]:
# 构建邻接表
graph = [[] for _ in range(c + 1)]
# 顶点信息
vertices = [{'vertex_id': i, 'offline': False, 'power_grid_id': -1} for i in range(c + 1)]
for u, v in connections:
graph[u].append(v)
graph[v].append(u)
# 初始化电网列表
power_grids = []
power_grid_id = 0
# DFS遍历连通分量
def dfs(u: int, pg_id: int, pg_heap: List[int]):
vertices[u]['power_grid_id'] = pg_id
heapq.heappush(pg_heap, u)
for v in graph[u]:
if vertices[v]['power_grid_id'] == -1:
dfs(v, pg_id, pg_heap)
# 遍历所有顶点,找到所有连通分量
for i in range(1, c + 1):
if vertices[i]['power_grid_id'] == -1:
power_grid = []
dfs(i, power_grid_id, power_grid)
power_grids.append(power_grid)
power_grid_id += 1
ans = []
for op, x in queries:
if op == 1: # 查询操作
if not vertices[x]['offline']:
ans.append(x)
else:
pg = power_grids[vertices[x]['power_grid_id']]
# 弹出所有离线的顶点
while pg and vertices[pg[0]]['offline']:
heapq.heappop(pg)
if pg:
ans.append(pg[0])
else:
ans.append(-1)
elif op == 2: # 离线操作
vertices[x]['offline'] = True
return ans
# 测试用例
if __name__ == "__main__":
c = 5
connections = [[1, 2], [2, 3], [3, 4], [4, 5]]
queries = [[1, 3], [2, 1], [1, 1], [2, 2], [1, 2]]
result = processQueries(c, connections, queries)
print(result) # 输出结果
.
#include <iostream>
#include <vector>
#include <queue>
#include <functional>
using namespace std;
// 顶点结构体
struct Vertex {
int vertexId;
bool offline;
int powerGridId;
Vertex(int id = 0) : vertexId(id), offline(false), powerGridId(-1) {}
};
void traverse(Vertex* u, int powerGridId, priority_queue<int, vector<int>, greater<int>>& powerGrid,
vector<vector<int>>& graph, vector<Vertex>& vertices) {
u->powerGridId = powerGridId;
powerGrid.push(u->vertexId);
for (int vid : graph[u->vertexId]) {
Vertex& v = vertices[vid];
if (v.powerGridId == -1) {
traverse(&v, powerGridId, powerGrid, graph, vertices);
}
}
}
vector<int> processQueries(int c, vector<vector<int>>& connections, vector<vector<int>>& queries) {
// 构建邻接表
vector<vector<int>> graph(c + 1);
vector<Vertex> vertices(c + 1);
for (int i = 0; i <= c; i++) {
vertices[i] = Vertex(i);
}
for (auto& conn : connections) {
int u = conn[0], v = conn[1];
graph[u].push_back(v);
graph[v].push_back(u);
}
// 存储所有电网(每个电网是一个最小堆)
vector<priority_queue<int, vector<int>, greater<int>>> powerGrids;
int powerGridId = 0;
// 遍历所有顶点,找到连通分量
for (int i = 1; i <= c; i++) {
Vertex& v = vertices[i];
if (v.powerGridId == -1) {
priority_queue<int, vector<int>, greater<int>> powerGrid;
traverse(&v, powerGridId, powerGrid, graph, vertices);
powerGrids.push_back(powerGrid);
powerGridId++;
}
}
vector<int> ans;
for (auto& q : queries) {
int op = q[0], x = q[1];
if (op == 1) { // 查询操作
if (!vertices[x].offline) {
ans.push_back(x);
} else {
// 获取顶点所在的电网
auto& powerGrid = powerGrids[vertices[x].powerGridId];
// 弹出所有离线的顶点
while (!powerGrid.empty() && vertices[powerGrid.top()].offline) {
powerGrid.pop();
}
if (!powerGrid.empty()) {
ans.push_back(powerGrid.top());
} else {
ans.push_back(-1);
}
}
} elseif (op == 2) { // 离线操作
vertices[x].offline = true;
}
}
return ans;
}
int main() {
int c = 5;
vector<vector<int>> connections = {{1, 2}, {2, 3}, {3, 4}, {4, 5}};
vector<vector<int>> queries = {{1, 3}, {2, 1}, {1, 1}, {2, 2}, {1, 2}};
vector<int> result = processQueries(c, connections, queries);
cout << "[";
for (size_t i = 0; i < result.size(); i++) {
cout << result[i];
if (i < result.size() - 1) {
cout << ", ";
}
}
cout << "]" << endl;
return0;
}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。