并查集
主要用于解决元素分组的问题。主要操作有集合(或单个元素)的合并和查询元素所在的集合。
元素以在同一棵树下为标志,认为在同一集合中。多个集合对应着多棵不同的树,组成了森林。
逻辑上是树形结构,实际上用数组存储元素所在集合的根节点。
合并
合并 x 和 y 两个元素时,不能直接合并两个元素,而是要合并两个元素所在树的根节点。
查询
查询 x 和 y 是否在同一个集合,是查询 x 和 y 对应的根节点是否相同。
合并示例


代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include<iostream> const int SIZE = 9; int parent[SIZE];
int find(int x) { while(x != parent[x]) { x = parent[x]; } return x; }
int r_find(int x) { if(x == parent[x]) return x; return r_find(parent[x]); }
void merge(int x, int y) { int x_root = find(x); int y_root = find(y); if (x_root != y_root) { parent[y_root] = x_root; } } int main() { for(int i = 1; i < SIZE; ++i) { parent[i] = i; } int x, y; for(int i = 1; i <= 6; ++i) { std::cin >> x >> y; merge(x, y); } for(int i = 1; i < SIZE; ++i) { std::cout << parent[i] << " "; } std::cout << std::endl; std::cout << "输入要查询的2个元素是否在一个集合:"; std::cin >> x >> y; std::cout << (find(x) == find(y) ? "在" : "不在") << std::endl; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| 输入: 1 3 1 2 5 4 2 4 6 8 8 7 输出parent数组: 1 1 1 5 1 6 6 6 输入要查询的2个元素是否在一个集合: 2 4 输出: 在
|
路径压缩