由最小生成树(MST)到并查集(UF)
背景
最小生成树(Minimum Spanning Tree)的算法中,克鲁斯卡尔算法(Kruskal‘s
algorithm)是一种常用算法.
代码
/**
* 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)的更多相关文章
- 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集
[题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...
- 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)
传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...
- 模板——最小生成树kruskal算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
- 最小生成树(Kruskal)(并查集)
最小生成树 时间限制: 1 Sec 内存限制: 64 MB提交: 11 解决: 2[提交][状态][讨论版] 题目描述 某个宇宙帝国有N个星球,由于宇宙的空间是三维的,因此每个星球的位置可以用三维 ...
- 最小生成树 - 克鲁斯卡尔 - 并查集 - 边稀疏 - O(E * logE)
#define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<cstring> #include<algorithm ...
- 【kruscal】【最小生成树】【并查集扩展】bzoj3714 [PA2014]Kuglarz
ORZ:http://www.cnblogs.com/zrts/p/bzoj3714.html #include<cstdio> #include<algorithm> usi ...
- ACM: 继续畅通工程-并查集-最小生成树-解题报告
继续畅通工程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Descri ...
- 并查集 (Union-Find Sets)及其应用
定义 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的 ...
- 【并查集】 不相交集合 - 并查集 教程(文章作者:Slyar)
最近写了一个多星期的并查集,一瞬间贴出这么多解题报告,我想关于并查集的应用先告一段落吧,先总结一下. 在网上看到一篇关于并查集比较好的教程(姑且允许我这么说吧),不转过来是在可惜.献给爱学习的你 文章 ...
随机推荐
- Visual Studio 2017 for Mac
Visual Studio 2017 for Mac Last Update: 2017/6/16 我们非常荣幸地宣布 Visual Studio 2017 for Mac 现已推出. Visual ...
- cocos2d-x 日志...
cocos2d-x 日志... http://blog.csdn.net/themagickeyjianan/article/details/39008297http://blog.csdn.net ...
- No.20 selenium学习之路之文件读写
1.open 使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. file_object = open('thefile.tx ...
- DOS命令大全(二)
一般来说dos命令都是在dos程序中进行的,如果电脑中安装有dos程序可以从开机选项中选择进入,在windows 系统中我们还可以从开始运行中输入cmd命令进入操作系统中的dos命令,如下图: 严格的 ...
- HDU 5115 Dire Wolf (区间DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115 题目大意:有一些狼,从左到右排列,每只狼有一个伤害A,还有一个伤害B.杀死一只狼的时候,会受到这 ...
- 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 ...
- git/github 生成密钥
当从本地提交文件到github的时候,提交不成功,报错,可能问题就是你还没有生成ssh秘钥 github要使用ssh密钥的原因: git使用https协议,每次pull, push都要输入密码,相当的 ...
- 企业级Docker Registry —— Harbor搭建和使用
本节内容: Harbor介绍 安装部署Harbor 环境要求 环境信息 安装部署harbor 配置harbor 配置存储 完成安装和启动harbor 访问Harbor 修改管理员密码 启动后相关容器 ...
- Spring Boot 教程demo
https://github.com/ityouknow/spring-boot-examples
- MySQL 20个经典面试题
1.MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联: 1. 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中: 2. 从:io线程——在 ...