并查集与带权并查集(转)

转自Chris_zzj的博客!


并查集

并查集是一个很高效算法,理解起来也很简单,写起来更简单。

①fat[i] = i;

②找到一个点的祖先

[cpp]  view plain  copy
  1. int findfat(int x)  
  2. {  
  3.     if(fat[x] == x) return x;  
  4.     return findfat(fat[x]);  
  5. }  

③二中的方法肯定不好,因为如果数据比较极端,那么并查集就退化成一个链了

如果加入了路径压缩,并查集这个算法就更高效了。

[cpp]  view plain  copy
  1. int findfat(int x)//递归写法  
  2. {  
  3.     if(fat[x] == x) return x;  
  4.     fat[x]=findfat(fat[x]);  
  5.     return findfat(fat[x]);  
  6. }  
[cpp]  view plain  copy
  1. int findfat(int x)//非递归写法 更好,因为不会RE  
  2. {  
  3.     int root=x;  
  4.     while(root != fat[root])//先要找到根节点r   
  5.     {  
  6.         root=fat[root];  
  7.     }  
  8.     int y=x;  
  9.     while(y!=root)  
  10.     {  
  11.         int fath=fat[y];  
  12.         fat[y]=root;  
  13.         y=fath;  
  14.     }  
  15.     return r;  
  16. }  
④合并

[cpp]  view plain  copy
  1. void join(int x,int y)  
  2. {  
  3.     int fatx=findfat(x),faty=findfat(y);  
  4.     if(fatx != faty)  
  5.     {  
  6.         fat[fatx]=faty;  
  7.     }  
  8. }  


带权并查集

带权值的并查集只不过是在并查集中加入了一个value[ ]数组
value[ ]可以记录很多种东西,不一定是类似距离这种东西,也可以是相对于根节点的状态
加入了权值,函数应该有一些改变
①找到一个点的祖先
[cpp]  view plain  copy
  1. int findfat(int x)  
  2. {  
  3.     if(fat[x] == x) return x;  
  4.     int tmp=fat[x];  
  5.     fat[x]=findfat(fat[x]);  
  6.     //在此处修改val比如:  
  7.     value[x]=value[tmp]+1;  
  8.     return fat[x];   
  9. }  

你可能感兴趣的:(并查集)