并查集—分离集合森林实现
来源:互联网 发布:音频dsp处理器数据 编辑:程序博客网 时间:2024/06/06 18:53
并查集总结
今天总结一下并查集,这个完了之后,寒假学的数据结构基础的模板类的题目差不多就完了,对于模板题,敲上10遍、20遍、30遍,那么模板就不是模板,就成为了你自己的东西,就好像 A+B 一辈子也忘不了,以后每天敲一遍模板题,加深对模板的理解。
并查集,一般使用的是 数组实现、树实现,其中数组实现时间复杂度较高,树实现也就是分离集合森林 查找、合并的时间复杂度不会
超过 O(log2n)
一、树实现
今天总结一下并查集,这个完了之后,寒假学的数据结构基础的模板类的题目差不多就完了,对于模板题,敲上10遍、20遍、30遍,那么模板就不是模板,就成为了你自己的东西,就好像 A+B 一辈子也忘不了,以后每天敲一遍模板题,加深对模板的理解。
并查集,一般使用的是 数组实现、树实现,其中数组实现时间复杂度较高,树实现也就是分离集合森林 查找、合并的时间复杂度不会
超过 O(log2n)
n个人,m对有亲戚关系的
10 7
1 2
2 3
2 4
3 4
5 6
6 7
8 9
初始化:{1} {2} {3} {4} {5} {6} {7} {8} {9} {10}
初步合并 {1,2} {2,3} {2,4} {3,4} {5,6} {6,7} {8,9} {10}
最终合并 {1,2,3,4} {5,6,7} {8,9} {10}
分离集合森林如下:
一、树实现
并查集中,每一个集合代表一个分离集合树,多个集合形成一个森林,树根当做集合的代表,每一个节点都有一个父指针来表示附属关系,根节点指向自身,在一个树高度很低的树种查找一个节点所用的时间很少。所以 并查集的分离集合树的 开辟一个秩的int 数据来保证构造的分离集合树的高度较低,在合并的时候,让较小的秩的根指向较大秩的根,若俩个秩相等,任意一个指向另一个,并且它的秩+1;
POJ 2524
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>const int N= 50001;using namespace std;struct node{ int data; // 节点数据域 int zhi; //秩 存放子树高度 int parent;//父节点}t[N];int n,m;int Find(int r)//查{ while(t[r].parent!=r)//判断双亲是不是自己 { r = t[r].parent; //循环查找X, } /* if(t[r].parent==r) //递归实现 return r; else return (Find(t[r].parent)); */ int i=r,j;//压缩路径 while (t[i].parent!=r)//i的父亲不是r,进行压缩 { j=t[i].parent;//记录i的父亲 t[i].parent=r;//改变i的父亲 i=j;//判断i的父亲 } return r;}void Merge(int x,int y)//并:合并x y的子树{ x = Find(x); //找x所在子树的编号 y = Find(y); if(t[x].zhi>t[y].zhi) //较小秩 指向 较大秩 { t[y].parent = x; //y链接到x上,x为父节点 } else { t[x].parent = y; if(t[x].zhi == t[y].zhi) //x连接y,y做为父节点 t[y].zhi++; //y的子树高度+1 }}void init(){ for(int i = 1;i<=n;i++) { t[i].data = i; t[i].zhi = 0;//初始化 树高度为0 t[i].parent = i;//父节点是自己 }}int main(){ int x,y,l=0; while(scanf("%d%d",&n,&m)) { if(n==0 && m==0) break; l++; init(); for(int i = 0;i<m;i++) { scanf("%d%d",&x,&y); Merge(x,y); } int sum = 0; for(int i = 1;i<=n;i++) { if(t[i].parent!=i) sum++; } printf("Case %d: %d\n",l,n-sum); } return 0;}
数组实现
#include <stdio.h>int bin[100010];int findx(int x){ int r=x; while(bin[r] !=r) r=bin[r]; return r;}void merge(int x,int y){ int fx,fy; fx = findx(x); fy = findx(y); if(fx != fy) bin[fx]=fy;}int main(){ int n,m,i,x,y,count;int t=1; while(~scanf("%d%d",&n,&m)) { if(n==0 && m == 0) break; for(i=1;i<=n;i++) { bin[i] = i; } for(i=1;i<=m;i++) { scanf("%d %d",&x,&y); merge(x,y); } for(count = 0, i=1;i<=n;i++) if(bin[i] == i) count ++; printf("Case %d: %d\n",t++,count); } return 0;}
0 0
- 并查集—分离集合森林实现
- 并查集及其链表与不相交集合森林实现
- 算法导论之不相交集合森林——并查集
- 十、森林与并查集---(0)什么是森林
- 并查集的森林封装
- 树的应用 森林 并查集
- 【bzoj3669】魔法森林 LCT+并查集
- hdoj 2874 Connections between cities 【并查集合并森林成一棵树 + LCA转RMQ】
- 【并查集】集合 set
- 集合(并查集)
- 重学数据结构系列之——森林之并查集(Disjoint set)
- 树结构练习——判断给定森林中有多少棵树-并查集
- 20131029: 并查集; 树与森林入门
- HDU 3367 Pseudoforest(伪森林)(并查集)
- hdu1325 Is It A Tree? (并查集+森林)
- (并查集第一课) 冗余关系 - 树/森林
- 哈理工OJ 1959 森林木(并查集)
- 十、森林与并查集---(7)游戏分组
- SharedPreferences访问与修改记录
- vs2010创建和使用动态链接库(dll)
- 贪吃蛇 by :jackfrued
- Web开发——PHP vs Java
- UFLDL 学习笔记——稀疏自动编码机(sparse autoencoder)
- 并查集—分离集合森林实现
- 微软企业库5.0 支持 MySql
- CentOS 5.6(X64)下编译安装LNMP平台(Nginx1.0.4+PHP5.3.6+Mysql5.5.12)
- 简单易学的机器学习算法——决策树之ID3算法
- Java中Array的常用方法
- 关于 Apple Metal API 的一些想法
- BZOJ 1934: [Shoi2007]Vote 善意的投票
- 转移指令的条件与机器码
- 我的学习计划