1.普通并查集

用于记录节点之间的连接关系,使得相互连通关系的点可以用他们共同的父节点来表示。对于父节点不同的点可以通过父节点的合并来改成相互连通。主要用于判断图的连通性(如kruskal算法中)。

int find(int x)
{
    if(x!=pre[x])//包括路径压缩
        pre[x]=find(pre[x]);
    return pre[x];
}

合并:

void join(int x,int y)
{
    int a=find(x);
    int b=find(y);
    if(a!=b)
        pre[a]=b;//只是简单的将节点合并
}

2.带权并查集
在一般并查集的基础上,在父节点的更改和合并时,同时记录下边的信息的改变。

int find(int x)
{
    if(x!=pre[x])//包括路径压缩
    {
    		int t=pre[x];//暂时记录下之前的父节点,便于更改路径压缩后的权值
    		pre[x]=find(pre[x]);
    		value[x]+=value[t];
    }
    return pre[x];
}

并:

void join(int x,int y)
{
    int a=find(x);
    int b=find(y);
    if(a!=b)
    {
        pre[a]=b;
        value[a]=-value[x]+value[y]+s;//并非每一个带权并查集都是这样更新
    }//s为x与y之间的边权,因为a,b之间的权值不知道,因此这样表示
}

3.种类并查集
和带权并查集一样,再设定一个数组group[x],对其赋不同的值表示他和他的父亲的关系,具体看题目。和带权并查集不同的是,这里有一个取模的操作,一般有几个种类就mod几,把权值的累加变成累加结果mod p。
重点在于合并,利用向量加减的关系画图求出关系式