并查集
来源:互联网 发布:mac 查看文件内容命令 编辑:程序博客网 时间:2024/05/29 01:56
功能
1、实现两个集合的合并2、查询一个元素属于哪个集合
实现
一共两个函数:1、查找当前元素a,属于哪个集合 :int getPar(int a)注意实现时需要做路径压缩,下图就是路径压缩的原理:![这里写图片描述](http://img.blog.csdn.net/20160823214627924)函数实现:int getPar(int a){ if(par[a] == a) return a; return par[a] = getPar(par[a]);}原理:par[a] = a;即当前集合的跟就是自己,即可返回;如果不是那么:要做的是getPar(par[a]),即递归的找根,此处我有时会傻逼写成getPar[a] 如果写成这种,就死循环了。递归要每次都进一步,如上图:即d的父亲不是d而是c,那么要找的是c的父亲才能一直向上递归。然后把当前的par[a] = getPar[a]即可实现路径压缩。
2、集合的合并此处简单,原理如下:![这里写图片描述](http://img.blog.csdn.net/20160823214654932)函数实现:void mergePar(int a,int b){ par[getPar(a)] = getPar(b);//a接到b上}即将a找到根节点后,将根节点的父亲置为b的根节点编号
效率
getPar的时间复杂度:(此处暂时未弄清楚)![这里写图片描述](http://img.blog.csdn.net/20160823214741018)
例题
poj 1611 http://poj.org/problem?id=1611n个学生分属m个团体,(0 < n <= 30000 , 0 <= m <= 500) 一个学生可以属于多个团体。 一个学生疑似患病,则它所属的整个团体都 疑似患病。已知0号学生疑似患病,以及每个 团体都由哪些学生构成,求一共多少个学生 疑似患病。
题解
#include <iostream>using namespace std;const int maxn = 30100;int par[maxn];void initPar(int n){ for (int i = 0; i <= n; ++i) { par[i] = i; }}int getPar(int a){ if(par[a] == a) return a; return par[a] = getPar(par[a]);}void mergePar(int a,int b){ par[getPar(a)] = getPar(b);//a接到b上}int n,m,total;int main() { while (scanf("%d %d",&n,&m)){ if(n ==0 && m == 0) break; initPar(n); total = 0; int nloop, tmp,tmp1; while (m--){ scanf("%d",&nloop); scanf("%d",&tmp1); nloop--; while (nloop--){ scanf("%d",&tmp); mergePar(tmp,tmp1); tmp1 = tmp; } } while (n--){ if(getPar(n) == getPar(0)) total++; } printf("%d\n",total); } return 0;}
0 0
- HDU3938 并查集 并查集
- 并查集(集并查)
- HDU1232 并查集<并>
- 并查集
- 数据结构-并查集
- 并查集
- 并查集!
- 并查集
- 并查集
- 并查集
- 并查集
- 并查集总结
- 并查集学习
- 并查集
- 并查集
- 并查集
- 所谓并查集
- 并查集
- GCC编译GDB调试程序
- mb中compute节点多个out节点的选择
- 定时刷新网页或跳转到新页面
- sudo: unable to resolve host
- java反射机制动态给属性赋值
- 并查集
- 在mb中动态获取XMLNSC下的namespac…
- 关于IO流的一些理解
- AL32UTF8和UTF8字符集
- 添加JSTL依赖到工程中
- Android Studio NDK 入门教程(4)--优雅的在C++中输出Logcat
- Bootstrap样例
- zephyr操作系统:第一节
- java io系列01之 "目录"