并查集

并查集

并查集是一种可以动态维护若干个不重叠的集合,并支持合并与查询的数据结构,并查集包含如下两个基本操作。
\(1\).get,查询一个元素属于哪一个集合。
\(2\).merge,把两个集合合并成一个集合。
并查集的关键点是要定义一种合理有效的归属关系表示方法。采用一棵树形结构储存每个集合,树上的每个节点都是一个元素,树根是集合代表的元素。。整个的并查集实际上是一个森林(若干棵树)。我们仍然可以维护一个数组\(fa\)来记录这个森林,用\(fa[x]\)保存x的父节点。特别的,令树根的fa值等于它自己。故,在合并两个集合时,只需连接两个树根(令其中一个树根为另一个树根的子节点,即\(fa[root1]\)=\(root2\)

路径压缩

对于一棵树,其中的每个节点都是属于根节点为代表的集合下的,在我们对任意节点进行get操作时,我们可以把访问过的每个节点都指向树根,这种操作叫路径压缩,采用路径压缩的并查集的每次\(get\)操作的均摊复杂度为\(O(logn)\)

1.并查集的储存与初始化

使用一个数组fa来保存父节点(根的父节点为自己)

int fa[size];
for(int i=1;i<=n;i++) fa[i]=i;//设有n个元素,起初所有元素各自构成一个独立的集合,即有n棵1个点的树

2.并查集的\(get\)操作

//若x时树根,则x就是集合代表,否则递归访问fa[x]直至根节点。
int get(int x){
      if(x!=fa[x]) fa[x]=get(fa[x])
      return fa[x];
}

3.并查集的merge操作

合并元素x和元素y所在的集合,等价于让x的树跟作为y的树根的子节点。、
 void merge(int x,int y){
  fa[get(x)]=get(y)
posted @ 2020-08-09 10:46  地球长大的赛亚人  阅读(94)  评论(0编辑  收藏  举报