并查集入门
来源:互联网 发布:中科大苏州软件学院 编辑:程序博客网 时间:2024/05/22 13:52
我是看着《啊哈!算法》这本书完成并查集的入门,本想举出另外的栗子,奈何。。。书上的栗子已经很贴切了。
首先引入一个问题:已知有10个土匪,警方需要需要一点点顺藤摸瓜最后挖出他们各自背后的团伙一锅端,经过一段时间的侦查警方的得到了9条确切线索,分别能说明那两个土匪的归顺关系。那么请问此次行动总共要打掉几个团伙?
输入数据如下:
按照第一行输入人数n,线索数m,接下来的m行输入线索,每行线索如1 2代表1号和2号土匪是一伙的。现提供一组数据以供后续讲解和程序测试:
10 91 23 45 24 62 68 79 71 62 4这组数据应该输出几呢?让我们一点点分析。
1:首先申请一个一维数组f,用下标1~10来标记这10个土匪,每个元素对应的数值来代表每个土匪的老大是谁。
2:进行初始化,一开始我们先假设各个土匪“各自为政”,即 f[1]=1, f[2]=2 ......f[i] = i ;都以自身为BOSS
3:开始处理线索,首先第一条线索1 2,可以发现1号和2号是一伙的,那么到底是让1号归顺2号还是2号归顺1号呢?这里我们先按照“靠左”法则,让2号归顺一号,即个f[2] = 1 ; 此时f数组变为
1 1 3 4 5 6 7 8 9 10
然后开始处理第二条线索,3 4,同理根据“靠左法则” f[4] = 3 ; 此时f数组变为:
1 1 3 3 5 6 7 8 9 10
继续第三条线索 5 2,已知f[5] = 5,说明5号的BOSS是自己,对于2号f[2] = 1 ;说明2号的BOSS是1号,此时仍然按照“靠左”法则的话,让2号归顺5号即f[2] = 5 ;那么1号强盗就不干了。为什么枪我的人(f[2] =1)?此时出现矛盾,怎么办呢??? 此时引入另一法则----->擒贼先擒王!!直接找2号的BOSS谈,让2号的BOSS 1号归顺5号即f[1]=5,矛盾解决!!第三条线索处理完毕,此时f数组为:
5 5 3 3 5 6 7 8 9 10
到这里有了靠左法则和擒贼先擒王法则以后的6条线索都能被顺利处理,这里不在赘述处理过程,直接给出每次处理以后的f数组
5 5 3 3 5 3 7 8 9 10
5 5 5 3 5 5 78 9 10
5 5 5 3 5 5 8 8 9 10
5 5 5 3 5 5 9 9 9 10
最终团伙关系清晰呈现在眼前:
2 1 3 4 6的BOSS是5号
10号自己当自己的BOSS
8 7的BOSS是9号
所以一共有三个团伙! 问题圆满解决,
ps:详细过程可以参照《啊哈!算法》 200页,下面给出解题代码:
#include <cstdio>#include <iostream>using namespace std ;int f[1000] ; //定义各个元素int n,m ; //总人数n和已知的关系的数目int x,y ; //一组关系 如 1 2代表1号2号为一伙 void init() //进行初始化{ for(int i = 1 ;i<=n ;i++) { f[i] = i ; }}int getf(int v) //不停的去找自己的宿主{ if(f[v] == v) return v ; else { f[v] = getf(f[v]) ; return f[v] ; }}void merge(int v,int u) //归并函数{ int t1,t2 ; t1 = getf(v) ; t2 = getf(u) ; if(t1 != t2) //按照左边优先的原则,让t2归顺t1 { f[t2] = t1 ; }}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { init() ; for(int i = 0 ;i<m ;i++) { scanf("%d%d",&x,&y) ; merge(x,y) ; } int sum = 0 ; //统计团伙数目sum for(int i = 1 ;i<=n ;i++) { if(f[i] == i) sum++ ; } printf("总共有%d个团伙\n",sum) ; } return 0 ;}
2015/4/7更新
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 并查集入门
- 亲戚关系 并查集入门
- 并查集--(初学,入门)
- 并查集入门基础
- 并查集入门笔记
- 并查集入门(1213)
- 并查集入门学习
- 并查集—入门
- 并查集入门--hd 2079 并查集模板
- Can’t connect to local MySQL server through socket 解决办法
- UVaOJ 490 Rotating Sentences
- android中的sqlite数据库
- Java JDBC和MySQL
- virtualBox虚拟机的一些配置
- 并查集入门
- ORACLE_基础十二(Profiles)
- BUPT OJ 147. Substring
- poj 3616 Milking Time DP
- a new client --- using httpclient or curl or requests
- hibernate基于hql的基本查询
- 未文档化函数ObReferenceObjectByName的说明
- ajax无刷新实时验证用户名密码
- 实现的局域网内大文件传输(ftp功能)