并查集

一、内容
由一个整型数组pre[]和两个函数find(),join()构成
二、作用
求连通分支数
三、find函数作用与实现
a、作用:找出指定x所在集合的boss(根节点)。
b、实现:

int find(int x){
   while(pre[x]!=x)
       x=pre[x];
   retuen x;
}

四、join函数作用于实现
a、作用:让指定的两个数x,y所在集合的其中一个boss成为另外一个boss,使这两个集合合并为同一个集合。
b、实现:

void join(int x,int y){
     int fx=find(x),fy=find(y);
     if(fx!=fy)
       pre[fx]=fy;
}

注:可通过rank函数优化合并集合函数

void Union(int i,int j){
     i=find(i);
     j=find(j);
     if(i==j) return;
     if(rank[i]>rank[j]) pre[j]=i;
     else{
          if(rank[i]==rank[j]) rank[j]++;
          pre[i]=j;
         }
 }

五、路径压缩算法的含义与实现
a、含义:使指定x的上一级直接为boss,提高效率
b、实现:

int find(int x){
    if(pre[x]==x)
        return x;
    return pre[x]=find(pre[x]);
}

总结
1、用集合中的某个元素来代表这个集合,该元素称为集合的代表元
2、对于每一个元素pre[x]指向x在树形结构上的父亲节点。(若x为根节点,则pre[x]=x)
3、判断两个元素是否为同一个集合,只要看他们代表元是否相同即可
4、一般来说,并查集分为三个操作:初始化,查找根节点,合并集合
初始化如下(某个元素上一级就是自己)

void Make_pre(int i){
     pre[i]=i;
}

5、汇总代码

const int N=100
int pre[N];
int rank[N];              //树高度
void Make_pre(int n){         //初始化函数,对录入的n个结点进行初始化
     for(int i=0;i<n;i++){ 
        pre[i]=i;        //每个结点的上一级都是自己
        rank[i]=1;       //每个结点树的高度都是1
     }
}
int find(int x){     //查找结点x的根节点
    if(pre[x]==x) return x;  
    return pre[x]=find(pre[x]);   //先找到根节点,然后pre[x]=根节点
}
bool is_same(int x,int y){        //判断结点是不是连通
     return find(x)==find(x);
} 
bool unite(int x,int y){     //令y的根结点的上级为x
     x=find(x);
     y=find(y);
     if(x==y) return false;
     if(rank[x]>rank[y]) pre[y]=x;
     else{
          if(rank[x]==rank[y])  rank[y]++;
          pre[x]=y;
          }
          return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值