码说 | 并查集(以HDU1232为例)
码说 | 并查集(以HDU1232为例)
- 欢迎大家关注Zane's平行光工作坊
- 并查集
- 题目如下
- 题意概括
- 解题思路
- 并查方法
- 具体代码
- 题毕
欢迎大家关注Zane’s平行光工作坊
这是Zane第一次使用 Markdown编辑器发表CSDN博客来记录自己的代码学习,还请各位多多指教。言归正传,请看才学到的并查集(以HDU1232为例)。
并查集
顾名思义,“合并”和“查找”。这说明,初始时并差集中的元素是不相交的,经过一系列的基本操作之后,最终合并成为一个大的集合。在整个算法过程中,程序通过查找小子集进行动态合并,最终汇聚为大子集,使相应的问题得以解决。
题目如下
题意概括
在已有的城镇数N中,寻找最小的道路修建数以致将所有的城镇串联起来。
解题思路
从题目样例角度分析,即首先输入两个整数N、M分别表示城镇数目和已有道路数,随即输入M对数值,分别表示每条已有道路所连接的两端城镇编号,最终输出结果即为我们想要的答案(至少需要修建多少条道路)。
题目思路可以这么理解——每个城镇拥有自己的城镇号ID并且其ID是固定的,通过初始化为每一个城镇设置一个相应的内容值num而num是可变的,即在后续的合并中会改变,此题我设置的是将每条路后端的数值覆盖前段数值。
并查方法
题目最重要的思想是并查集,其核心就是代码中的find(x)查找函数和merge(a,b)合并函数。那我们便先解读一下这两个函数。
find(x)查找方法和merge(a,b)合并方法有着相对独立的关系,首先两个方法是独立的,find(x)查找方法在代码中使用了递归调用,其主要作用查找相同代号的城镇;而merge(a,b)方法则是借用了find(x)方法将拥有相同代号的城镇进行合并,整个过程又通过for循环将所有相同代号的城镇汇聚为各个大集合,那最终的结果便是大集合数目减1。
具体代码
// An highlighted block
#include<stdio.h>
int fa[1001]; //定义父亲数组,表示已经编号的城镇,保证城镇数目的可行性 int find(int x) //定义find方法,利用递归将城镇内容数相同化为一个整体
{if(fa[x]!=x)fa[x]=find(fa[x]);return fa[x];
}void merge(int a, int b) //定义merge方法,将道路后端的值赋给前端
{int x,y;x=find(fa[a]);y=find(fa[b]);if(x!=y)fa[x]=y;
}int main()
{int n,m,i,a,b,cnt=0; //n表示城镇数量 while(1){cnt=0; //定义cnt,表示增加道路的初始值为0 scanf("%d",&n); //输入n,表示城镇数目 if(n<=0)break; //如果n为非正数,则跳出循环,程序结束 for(i=1; i<=n; i++)fa[i]=i; //利用for循环为每一个城镇编号scanf("%d",&m); //输入m,表示道路数目 for(i=0; i<m; i++) {scanf("%d%d",&a,&b); //输入每一条道路的两端城镇编号 merge(a,b);}for(i=1; i<=n; i++)if(find(i)==i) //for循环完成相同数值的匹配 cnt++; //cnt次数增加表示道路需要扩建 printf("%d\n",cnt-1); //cnt-1表示至少要建立的数目 }return 0;
}
初始设置:
城镇ID | Value |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
道路情况:
查找合并
输入1 2:
城镇ID | Value |
---|---|
1 | 2 |
2 | 2 |
3 | 3 |
输入1 2:
城镇ID | Value |
---|---|
1 | 2 |
2 | 2 |
3 | 3 |
输入2 1:
城镇ID | Value |
---|---|
1 | 1 |
2 | 1 |
3 | 3 |
通过图表演示可得最终形成了两个大集合(1,2)和(3),故cnt=2-1=1。
题毕
谢谢关注。
码说 | 并查集(以HDU1232为例)相关推荐
- 简单易懂的并查集算法以及并查集实战演练
文章目录 前言 一.引例 二.结合引例写出并查集 1. 并查集维护一个数组 2. 并查集的 并 操作 3. 并查集的 查 操作 4. 基本并查集模板代码实现--第一版(有错误后面分析) 4.1 Jav ...
- C++用并查集Disjoint union实现connected component连通分量(附完整源码)
C++用并查集Disjoint union实现connected component连通分量 C++用并查集Disjoint union实现connected component连通分量完整源码(定义 ...
- C++并查集Disjoint Set(附完整源码)
C++并查集Disjoint Set 并查集Disjoint Set算法的完整源码(定义,实现,main函数测试) 并查集Disjoint Set算法的完整源码(定义,实现,main函数测试) #in ...
- C语言实现并查集(Disjoint set或者Union-find set)(附完整源码)
实现实现并查集 实现并查集(Disjoint set或者Union-find set)的完整源码(定义,实现,main函数测试) 实现并查集(Disjoint set或者Union-find set) ...
- 【无码专区9】序列统计(带权并查集 + 前缀和建边 + dp)
因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dl ...
- HDU1232 畅通工程【并查集】
畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 并查集hdu1232
应该是最主要的题 開始还是没有理解透彻 没有理解透彻就不要急着做题 并查集说白了就是把全部的点看看能归成几个集 合 所以首先推断这两点是否在一个集合范围内 假设没在一个集合范围内 就把小的集合赋给大的 ...
- hdu1232(简单并查集)
畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- Hdu1232 畅通工程 【并查集】
http://acm.hdu.edu.cn/showproblem.php?pid=1232 题目大意:有几个集合,问最少需要连几根线才能把这些集合并为一个集合. N个集合的话就需要N-1条路就行了, ...
最新文章
- nyoj116士兵杀敌2
- Android(四)——View和ViewGroup
- OpenNRE 2.0:可一键运行的开源关系抽取工具包
- Scala学习笔记-环境搭建以及简单语法
- LeetCode MySQL 1205. 每月交易II(union all)*
- 英雄无敌3高清 Android,安卓TOP10:《英雄无敌3》高清重制版上架
- 基于新型存储的大数据存储管理
- python变量自加一_Python个人练习项目 2-1
- 高清人脸数据集汇总 (主要用于人脸生成、分割任务)
- 四叶草启动引导配置工具 !Clover Configurator中文版下载!
- linux卸载intel驱动程序,Linux的英特尔图形驱动程序调试工具删除Android支持
- css的外链写法,纯CSS代码为外链增加图标
- 基于机会网络环境模拟器的命名数据容迟网络的设计与实现
- SAP FICO 第二节 LSMW导入财务科目
- 64位电脑安装32位系统不能引导启动
- 服务器开机显示f1 f2,开机按f1的解决方法|开机按f2的解决方法|电脑开机按f1怎么解决...
- CCF-201809-3
- android系统是什么意思
- echarts多坐标轴图表
- JAVA:实现CircularBuffer环形缓冲器算法(附完整源码)