并查集(模版)洛谷P3367

并查集(模版)洛谷P3367b

1、算法主要操作
包括查Find(x)和合并Union(x,y)两个操作
在这里插入图片描述

2、算法优化
(1)查操作的路径压缩
Find(x)中一次循环找到x所在树的根结点,第二次循环,修改结点的par[]值,使得查找路径上的所有结点的父亲结点都变为这个集合的根结点,从而实现了路径压缩。
(2)合并操作的小树合并到大树中
设置一个数组height[i]表示根结点为i的集合的所有结点个数
在合并操作时,比较两颗树的height值,将值小的树的根结点的par[]修改为值大的根结点。下面是个例子,忘记树的双亲表示法,再去看看王道书。
在这里插入图片描述

对应模版题目洛谷P3367题

#include<bits/stdc++.h>
using  namespace std;
const int MAXcount = 100000;
int par[MAXcount],height[MAXcount];
//par[i]表示i结点的父结点 “par[i]=-1”表示为根结点
//height[i]表示以i为根结点的树的结点个数
int Find(int x)//返回x的父亲结点
{
    
    
    int ini = x;
    while(1){
    
    
        if(par[x]==-1){
    
    
            //朴素
//            return x;
            break;
        }
        x=par[x];
    }
    //优化--路径压缩,再重复一次查找根结点操作,
    //每查找完一次父亲结点,
    //就将该结点的父亲par[]设置为该树的根结点
    //(也就是上一次循环查找到的x)
    while(1){
    
    
        if(par[ini]==-1){
    
    
            break;;
        }
        int zj = ini;
        ini=par[ini];
        par[zj]=x;
    }
    return x;
}
void Union(int x,int y)
{
    
    
    int rootx,rooty;
    rootx=Find(x);rooty=Find(y);
    if(rootx!=rooty){
    
    //如果根结点不同,进行合并操作
        //朴素--从x和y集合的根结点中随机选取一个作为另一个集合的根结点,完成合并操作
//        par[rooty]=par[rootx];
        //优化--选择树高小的合并到树高(集合的结点个数)大的根结点下
        if(height[rooty]>=height[rootx]){
    
    //如果y集合的结点数大于x集合的结点数,则将x集合合并到y结合的根结点下
            par[rootx]=rooty;
            height[rooty]+=height[rootx];//同时更新树高
        }else{
    
    
            par[rooty]=rootx;
            height[rootx]+=height[rooty];
        }
    }
}

int main()
{
    
    
    int N,M;
    memset(par,-1,sizeof(par));//初始化为-1,每个结点刚开始都是一个集合,所以其父结点为-1,表示其为根结点
    memset(height, 0, sizeof(height));//初始化数组为0
    cin>>N>>M;
    for(int i=0;i<M;i++){
    
    
        int z,x,y;
        cin>>z>>x>>y;
        if(z==1){
    
    
            Union(x,y);//合并集合x和y
        }else{
    
    
            int roox=Find(x);//查找x结点的父亲结点
            int rooy=Find(y);//查找y结点的父亲结点
            if(roox==rooy)cout<<"Y"<<endl;//比较两结点的父亲结点是否相同,可知是否在同一集合之中
            else cout<<"N"<<endl;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_47696370/article/details/129463132