并查集基本操作

并查集的两种基本操作,查找与合并。

1.查找根节点

查找节点x 的根节点r ,并将所有途经节点的父节点修改为根节点r 。

修改后的子树会变成一个只由叶子节点与唯一一个根节点构成的,深度为2的树。

int find_F(int x)
{
    int r= x;
    while(pre[r]!= r)
    {
        /*寻找根节点*/
        /*循环自下到上查找x所在枝的每个父节点*/
        /*直到找到根节点为止,记录根节点*/
        r= pre[r];
    }
    int i= x, j;
    while(i!= r)
    {
        /*路径压缩*/
        /*自下至上修改,从x 到根节点r,经过的所有节点,其父节点都修改为r */
        /*将子树变成一个只由叶子节点和唯一一个根节点构成的,深度为2的树*/
        j= pre[i];
        pre[i]= r;
        i= j;
    }
    return r;
}

2.合并

当给出的两个节点不在一棵树上时,合并两棵树,把其中一个根节点变为另一个根节点的子节点。

void join(intx,int y)
{
    int a=find_F(x);
    int b=find_F(y);
    /*每次对x 调用find_F()函数,都会再次刷新x 和其所有父节点*/
    if(a!=b)
    {
        /*如果两节点的根节点不同,则他们不连通*/
        /*则将根节点a 变成根节点b 的子节点,把两棵树合为一棵*/
        pre[a]=b;
        /*需要注意的是:此时节点a 的其他子节点,其父节点还是a*/
    }
}

3.初始化

void into()
{
    /*初始化*/
    for (int i= 1; i<= maxn; i ++)
    {
        /*每个节点一开始的父节点是自己*/
        pre[i]= i;
    }
}
原文地址:https://www.cnblogs.com/Amaris-diana/p/10608093.html