ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

并查集

2022-07-08 20:00:45  阅读:121  来源: 互联网

标签:sz fx int fy 查集 dep 深度


 1 //-----并查集的初始化-----
 2 
 3 //一开始有n个元素,互相独立,则构成了n个集合,每个集合的代表元素就是它本身
 4 
 5 const int maxn = 100010;
 6 
 7 int fa[maxn + 1];   //fa数组记录每个元素由谁代表
 8 int sz[maxn + 1];   //sz数组记录每个集合的元素个数
 9 int dep[maxn + 1];  //dep数组记录每个集合的树深度
10 
11 inline void Initialize(int n){
12     for (int i = 1;i <= n;i++){ //一共有n个点
13         fa[i] = i;              //把代表元素设置为自己
14         sz[i] = dep[i] = 1;     //一开始的深度就是1,子树大小也是1,因为只有自己孤零零的一个元素
15     }
16     return;
17 }
18 
19 //-----集合合并-----
20 
21 int Findset(int x){     //这个是用来找代表元素的函数,递归找
22     if (fa[x] == x){
23         return x;
24     }
25     return Findset(fa[x]);
26 }
27 
28 void Union(int x, int y){
29     int fx = Findset(x);
30     int fy = Findset(y);
31     if (fx == fy){      //如果发现是一家子的,那得了直接完事儿了
32         return;
33     }
34     fa[fx] = fy;        //否则我们就搞个强扭的瓜,扭到一起去  反过来写也是可以
35     return;
36 }
37 
38 //-----路径压缩-----
39 
40 //大致思路就是在查询的操作过程中,把沿途经过的每一个节点的fa都设置为集合的代表元
41 
42 int QuicklyFindset(int x){
43     if (x == fa[x]){    //如果就是代表元素就直接返回咯
44         return x;
45     }
46     fa[x] = QuicklyFindset(fa[x]);      //在不是的情况下每一次都设置一遍
47     return fa[x];
48 }
49 
50 /*
51 上述代码简写版:
52 int QuicklyFindset(int x){
53     return x == fa[x] ? x : (fa[x] == QuicklyFindset(fa[x]));
54 }
55 */
56 
57 //-----启发式合并-----
58 
59 //log的复杂度
60 
61 //大体思路:在合并集合的过程中,我们尽量选择包含元素个数少的集合,将它合并到另一个集合之中去,使要改变代表元的元素尽可能的少
62 //这种将较小的集合合并到较大的集合之中的方法被称为 启发式合并,在其他的数据结构中也很常见
63 
64 void HeuristicUnion(int x, int y){
65     int fx = Findset(x);
66     int fy = Findset(y);
67     if (fx == fy){
68         return;
69     }
70     if (sz[fx] > sz[fy]){
71         swap(fx, fy);   //确定谁是骡子谁是马
72     }
73     fa[fx] = fy;
74     sz[fy] += sz[fx];   //子树的大小也要加起来
75     return;
76 }
77 
78 //-----按深度合并-----
79 
80 //log的复杂度
81 
82 //大体思路:每一次合并的过程中,将深度较小的集合合并到深度较大的一方去,并更新一下新集合的深度
83 //值得一提的是,在路径压缩的时候,可能会破坏维护的深度值,但其实整体算法的复杂度不会变差
84 
85 void DeepUnion(int x, int y){
86     int fx = Findset(x);
87     int fy = Findset(y);
88     if (fx == fy){
89         return;
90     }
91     if (dep[fx] > dep[fy]){
92         swap(fx, fy);
93     }
94     fa[fx] = fy;
95     if (dep[fx] == dep[fy]){    //只有两棵树深度相等的时候才会更新
96         dep[fy]++;
97     }
98     return;
99 }

 

标签:sz,fx,int,fy,查集,dep,深度
来源: https://www.cnblogs.com/Conqueror712/p/16459497.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有