并查集
并查集
-
并查集有两种操作——查询,合并。
查询通常用来求联通块中各节点的父节点。
而合并则可统一两点的父节点。
-
初始化
int f[N]; for(int i = 0;i<n;i++){ //每个元素都是单独的一个集合,则他们的根都是自己 f[i] = i; }
-
查询x的根节点
int find(int x){ return f[x] == x ? x : (f[x]=find(f[x])); }
这个三目表达式
f[x] == x
,判断x
的父节点是不是他自己,如果是,x
就是根可以返回find(f[x])
,若x
还有父亲,则查找x
的父亲的父亲,直到有一个点的父亲是自己f[x] = find(f[x])
,便于后续找根:将x
的父亲重置为x
的父亲的父亲,最终x
的父亲就是x
的根 -
合并
//其实不用刻意写函数,直接在主函数中写亦可 void unionSet(int x, int y) { x = find(x); y = find(y); //若x与y有共同的根,说明x和y在同一个集合里 if (x == y) return; //令x和y有相同的根 fa[x] = y; return; }