l2-013 红色警报java并查集
时间: 2025-06-11 09:18:21 浏览: 23
### L2-013 红色警报 Java 并查集 实现与解题思路
L2-013 红色警报问题通常涉及图的连通性分析,使用并查集(Union-Find)是一种高效的解决方案。以下是基于并查集的实现和解题思路。
#### 解题思路
1. **初始化并查集**:为每个城市分配一个独立的集合,初始时每个城市的父节点是自身。
2. **处理边的关系**:对于每一对有直接联系的城市,通过并查集的合并操作将它们归入同一集合。
3. **统计连通分量的数量**:在所有关系处理完毕后,统计有多少个不同的连通分量,即有多少组相互有联系的城市。
4. **输出结果**:根据题目要求输出连通分量的具体信息或数量。
#### Java 并查集实现代码
以下是一个完整的 Java 实现代码:
```java
import java.util.*;
public class Main {
private static int[] parent; // 并查集数组,用于存储每个节点的父节点
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt(); // 城市数量
int M = scanner.nextInt(); // 道路数量
// 初始化并查集
parent = new int[N];
for (int i = 0; i < N; i++) {
parent[i] = i;
}
// 处理道路关系
for (int i = 0; i < M; i++) {
int cityA = scanner.nextInt();
int cityB = scanner.nextInt();
union(cityA, cityB);
}
// 统计连通分量数量
Set<Integer> connectedComponents = new HashSet<>();
for (int i = 0; i < N; i++) {
connectedComponents.add(find(i));
}
// 输出结果
System.out.println(connectedComponents.size());
for (Integer root : connectedComponents) {
List<Integer> group = new ArrayList<>();
for (int i = 0; i < N; i++) {
if (find(i) == root) {
group.add(i);
}
}
Collections.sort(group); // 按编号排序
System.out.print(group.size() + " ");
for (int city : group) {
System.out.print(city + " ");
}
System.out.println();
}
}
// 查找操作:路径压缩
private static int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
// 合并操作
private static void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
parent[rootX] = rootY;
}
}
}
```
#### 代码解析
1. **初始化**:`parent` 数组用于记录每个节点的父节点,初始时每个节点的父节点是其自身[^5]。
2. **查找操作**:`find` 方法实现了路径压缩,确保每次查找的时间复杂度接近 O(1)。
3. **合并操作**:`union` 方法将两个节点所在的集合合并为一个集合。
4. **统计连通分量**:通过 `Set` 数据结构记录所有不同的根节点,这些根节点代表了不同的连通分量。
#### 注意事项
- 输入数据中可能包含重复的道路关系,但并查集的特性可以自动忽略重复的合并操作。
- 输出时需要对每个连通分量内的城市按编号从小到大排序[^6]。
阅读全文
相关推荐




















