背景

最小生成树(Minimum Spanning Tree)的算法中,克鲁斯卡尔算法(Kruskal‘s
algorithm)是一种常用算法.

在克鲁斯卡尔算法中的一个关键问题是如何判断图中的两个点是否形成环(cycle),那么一种高效的判断方式就是使用并查集技术(Union-Find).

代码

/**
* Created by 浩然 on 4/19/15.
* 快速并查集
* 参考:普林斯顿大学 algorithms 4th edition
*
* 考虑一个问题:
* 一个城市需要将所有的路连起来以保证城市的畅通
* 在开始这个工程前,已经有一些路是连通的了,那么还需要在哪里修多少条路才能用最小的代价完成?
* 由于解决这个问题,只需要知道有多少个连通组件(已经连通的路的集合),
* 所以我们不关心每个连通组件内部的细节(某组件内部路线的布局)。
* 所以我们用并查集(Union-Find)的技术来做.(如果关心细节,比如要给出连通组件的路径,就用DFS技术)
*
* 并查集就像它的名字所述,提供两个操作:
* 1:将给定的点所在的连通组件找出来;
* 2:将两个点连通
*
*/
public class FastUnionFind {
/**
* 父节点集
*/
private int parent[];
/**
* 每个连通组件的大小
*/
private int treeSize[];
/**
* 连通组件的个数
*/
private int componentsCount; public FastUnionFind(int n) {
parent = new int[n];
treeSize = new int[n];
componentsCount = n;
for(int i = 0; i < n; i ++) {
parent[i] = i;
treeSize[i] = 1;
}
} /**
* 连通组件的个数
* @return
*/
public int componentsCount() {
return this.componentsCount;
} /**
* 验证给定编号的界
* @param which
*/
private void validate(int which) {
int n = this.parent.length;
if (which < 0 || which >= n) {
throw new IndexOutOfBoundsException("index which 越界!");
}
} /**
* 找到which属于哪个连通组件
* 意即找出它所在连通组件的代表
*
* @param which 索引或编号
* @return which所在的连通组件的代表
*/
public int find(int which) {
validate(which);
int root = which;
//不断向根回溯
while (root != parent[root]) {
root = parent[root];
} //全路径压缩-效率的关键
//因为我们只关心给定的索引所在组件的根是谁
//所以一个自然的想法就是让所有组件只需要一步就可以找到根
//换句话说,就是让树的高度尽可能的为2
//那么这里既然来到了处理find(which)的上下文,就对它所在的组件进行路径压缩
while (which != root) {
int newParent = parent[which];
parent[which] = root;
which = newParent;
}
return root;
} /**
* 求a、b间是否连通
* @param a 其中一点
* @param b 另一个点
* @return 如果连通返回真,否则返回假
*/
public boolean isConnected(int a,int b) {
//并查的重要意义之一就是测试两点之间是否具有连通性
//自然的,就转化成为它们是否属于同一个连通组件
//这里利用了连通的传递性 x->y,y->z,则x->z
return find(a) == find(b);
} /**
* 将a和b所在的连通组件合并
*
* 意即将a和b连通
*
* @param a 其中一点
* @param b 另一个点
*/
public void union(int a,int b) {
validate(a);
validate(b);
int rootA = find(a);
int rootB = find(b);
//这里利用平衡的思想
//将更小的树挂到更大的树上
if (treeSize[rootA] < treeSize[rootB]) {
parent[rootA] = rootB;
treeSize[rootB] += treeSize[rootA];
} else {
parent[rootB] = rootA;
treeSize[rootA] += treeSize[rootB];
}
//既然合并,连通组件就少了一个
this.componentsCount--;
}
}



由最小生成树(MST)到并查集(UF)的更多相关文章

  1. 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

    [题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...

  2. 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)

    传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...

  3. 模板——最小生成树kruskal算法+并查集数据结构

    并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...

  4. 最小生成树(Kruskal)(并查集)

    最小生成树 时间限制: 1 Sec  内存限制: 64 MB提交: 11  解决: 2[提交][状态][讨论版] 题目描述 某个宇宙帝国有N个星球,由于宇宙的空间是三维的,因此每个星球的位置可以用三维 ...

  5. 最小生成树 - 克鲁斯卡尔 - 并查集 - 边稀疏 - O(E * logE)

    #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<cstring> #include<algorithm ...

  6. 【kruscal】【最小生成树】【并查集扩展】bzoj3714 [PA2014]Kuglarz

    ORZ:http://www.cnblogs.com/zrts/p/bzoj3714.html #include<cstdio> #include<algorithm> usi ...

  7. ACM: 继续畅通工程-并查集-最小生成树-解题报告

    继续畅通工程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Descri ...

  8. 并查集 (Union-Find Sets)及其应用

    定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的 ...

  9. 【并查集】 不相交集合 - 并查集 教程(文章作者:Slyar)

    最近写了一个多星期的并查集,一瞬间贴出这么多解题报告,我想关于并查集的应用先告一段落吧,先总结一下. 在网上看到一篇关于并查集比较好的教程(姑且允许我这么说吧),不转过来是在可惜.献给爱学习的你 文章 ...

随机推荐

  1. Visual Studio 2017 for Mac

    Visual Studio 2017 for Mac Last Update: 2017/6/16 我们非常荣幸地宣布 Visual Studio 2017 for Mac 现已推出. Visual ...

  2. cocos2d-x 日志...

    cocos2d-x  日志... http://blog.csdn.net/themagickeyjianan/article/details/39008297http://blog.csdn.net ...

  3. No.20 selenium学习之路之文件读写

    1.open 使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. file_object = open('thefile.tx ...

  4. DOS命令大全(二)

    一般来说dos命令都是在dos程序中进行的,如果电脑中安装有dos程序可以从开机选项中选择进入,在windows 系统中我们还可以从开始运行中输入cmd命令进入操作系统中的dos命令,如下图: 严格的 ...

  5. HDU 5115 Dire Wolf (区间DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115 题目大意:有一些狼,从左到右排列,每只狼有一个伤害A,还有一个伤害B.杀死一只狼的时候,会受到这 ...

  6. Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value

    Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...

  7. git/github 生成密钥

    当从本地提交文件到github的时候,提交不成功,报错,可能问题就是你还没有生成ssh秘钥 github要使用ssh密钥的原因: git使用https协议,每次pull, push都要输入密码,相当的 ...

  8. 企业级Docker Registry —— Harbor搭建和使用

    本节内容: Harbor介绍 安装部署Harbor 环境要求 环境信息 安装部署harbor 配置harbor 配置存储 完成安装和启动harbor 访问Harbor 修改管理员密码 启动后相关容器 ...

  9. Spring Boot 教程demo

    https://github.com/ityouknow/spring-boot-examples

  10. MySQL 20个经典面试题

    1.MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联: 1. 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中: 2. 从:io线程——在 ...