由最小生成树(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)
最近写了一个多星期的并查集,一瞬间贴出这么多解题报告,我想关于并查集的应用先告一段落吧,先总结一下. 在网上看到一篇关于并查集比较好的教程(姑且允许我这么说吧),不转过来是在可惜.献给爱学习的你 文章 ...
随机推荐
- Django Rest Framework----ModelViewSet视图 ModelViewSet源码分析
一.视图类 #bookview是一个视图类,继承自ModelViewSet class BookView(ModelViewSet): throttle_classes = [VisitThrottl ...
- C++中关于位域的概念
原文来自于http://topic.csdn.net/t/20060801/11/4918904.html中的回复 位域 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位 ...
- Webmin试玩
安装: # cd /opt # wget http://www.webmin.com/jcameron-key.asc # wget http://www.webmin.com/download/rp ...
- Python模块:Random(未完待续)
本文基于Python 3.6.5的官文random编写. random模块简介 random为各种数学分布算法(distributions)实现了伪随机数生成器. 对于整数,是从一个范围中均匀选择(u ...
- iconfont-矢量图标字体
二.矢量图标使用 1.进入:http://www.iconfont.cn/ 搜索你图标的关键字,然后将需要的图标字体加入购物车 加入购物车之后,添加到项目 2.点击查看在线连接,生成css代码,把代 ...
- day05作业
一.1.switch 2.字符串 3.表达式1 4.break 5.continue 二.1.B 2.A 3.BD 4.D 5.B 6.B 7.A 8.D 9.D 10.B 三.1.√ 2.√ 3.× ...
- 洛谷P1186玛丽卡
传送门啦 先跑一遍最短路,将最短路的路径记录下来,然后枚举每一条最短路的边,将其断掉,记录此时的1-n的时间,取其中最大的一个时间即为所求. (通过 $ cut[][] $ 和 $ f[] $ 进行操 ...
- C++ 实现memcpy和strcpy
/** * @Method: Memcpy * @Access: public * @Return: void * * @Param : dst - 目的起始地址 * @Param : src - 源 ...
- Spring整合junit测试
本节内容: Spring整合junit测试的意义 Spring整合junit测试 一.Spring与整合junit测试的意义 在没整合junit之前,我们在写测试方法时,需要在每个方法中手动创建容器, ...
- 一步一步学习IdentityServer4 (6) Connect-OpenId Cookies SignIn SignOut 那些事
先来看下下面的配置: JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication( o ...