并查集--求解等价问题
来源:互联网 发布:matlab求矩阵的相角 编辑:程序博客网 时间:2024/05/29 07:10
什么是并查集
有多个集合,集合内有多个元素
并查集算法用来查找一个元素所属的集合,合并两个元素各自所属的集合。称为并查集
算法举例
亲戚关系的等价问题,犯罪团伙的头目。
给出很多人的亲戚相互间关系,查找任意两人是否为亲戚。
多个犯罪分子各自在自己的团伙中,找到犯罪团伙的数量。
算法思路
使用树的数据结构来实现并查集算法。
关键点:
1. 初始化集合,刚开始每个元素为一个集合,该元素就代表了该集合;如果有多个元素,根元素代表一个集合。根节点的parent指针指向自己。(元素间虽然有父子关系但是不意味者有从属关系,只是起到联系集合元素的作用)
2. 查找一个元素所属的集合。找该元素所在集合的根节点。
3. 合并集合。为了使合并后的树的高度更小,需要将高度较小的树作为高度较大的树的子树。若两树的高度相等需要将高度+1;
算法实现
java实现
package aha_algorithm;import java.io.BufferedReader;import java.io.InputStreamReader;public class MergeSearchSet { public static class MSSNode{ int id;//元素编号 int rank;//树的高度称为秩 int parent;//父节点下标 } static int elementNum; static int relationNum; static MSSNode[] MSSTree; /** * @param args */ public static void main(String[] args) { initSet(); judgeRelation(); } public static void initSet(){ BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); try { String[] inLine = input.readLine().split(" "); elementNum= Integer.valueOf(inLine[0]); relationNum = Integer.valueOf(inLine[1]); MSSTree = new MSSNode[elementNum]; //初始化关系树 for (int i = 0; i < elementNum; i++) { MSSNode tempNode = new MSSNode(); tempNode.id=i; tempNode.rank=0; tempNode.parent=i; MSSTree[i]= tempNode; } //获取关系并 合并 for (int i = 0; i < relationNum; i++) { String[] relation = input.readLine().split(" "); int idLeft= Integer.valueOf(relation[0]); int idRight = Integer.valueOf(relation[1]); mergeSet(idLeft, idRight); } }catch(Exception e){ e.printStackTrace(); } } static int findSet(int id){ if(id == MSSTree[id].parent){ return id; } return findSet(MSSTree[id].parent); } static void mergeSet(int idLeft,int idRight){ int parentLeft = findSet(idLeft); int parentRight = findSet(idRight); if(MSSTree[parentLeft].rank < MSSTree[parentRight].rank){ MSSTree[parentLeft].parent = parentRight; }else{ MSSTree[parentRight].parent = parentLeft; if(MSSTree[parentLeft].rank == MSSTree[parentRight].rank){ MSSTree[parentLeft].rank++; } } } static void judgeRelation(){ BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); try { String[] inLine = input.readLine().split(" "); int id1, id2; id1 = Integer.valueOf(inLine[0]); id2 = Integer.valueOf(inLine[1]); if(findSet(id1)==findSet(id2)){ System.out.println(id1+"和"+id2+"是亲戚"); }else{ System.out.println(id1+"和"+id2+"不是亲戚"); } }catch(Exception e){ e.printStackTrace(); } }}
时间复杂度
主要时间在查找元素所在的集合即找根节点。所有时间复杂度为logN。N为元素个数
阅读全文
0 0
- 并查集--求解等价问题
- 树的等价问题,并查集
- 并查集求解问题
- 并查集经典扩展-pku1182(食物链)-并查集用于等价类问题
- 等价类和并查集
- 并查集实现等价类
- 并查集实现等价类
- 用并查集求解连通分量问题
- Dominos<并查集求解>
- 并查集的表示与等价分类
- POJ1611 The Suspects 并查集求解
- Virtual Friends<并查集+map求解>
- 并查集问题
- 并查集问题
- 并查集问题
- 并查集问题
- 并查集问题
- POJ 1611:The Suspects 并查集求解
- 你知道吗?为何C语言函数调用要堆栈,而汇编却不需要?
- 蓝桥杯训练:合并石子
- 3
- usaco5.4.3 Telecowmunication
- 简明C语言教程(一)前言
- 并查集--求解等价问题
- Source Insight中的条件编译
- D -棋盘问题
- 类的无参方法
- 日志文件的管理
- JavaScript数组拓展(js数组form, of, copyWithin, find, fill, includes方法介绍)
- ArchLinux使用交叉编译工具链编译u-boot时提示找不到libstdc++.s0.6和libz.so.1
- TCP三次握手与四次挥手
- php中的修饰符public,protected,private