(并查集)求给定图G的连通分量的数目
2016-10-27 15:23
267 查看
本总结是是个人为防止遗忘而作,不得转载和商用。
如:某国家有N个小岛组成,经过多年的基础设施积累,若干岛屿之间建立了若干桥梁。先重新完善该国的行政区划,规定只要有桥梁连接的岛屿则归属同一个城市(可以通过其他岛屿中转),问该国一共多少个城市?
1,i和i一定属于同一类
2,若i和j属于同一类,则j和i也属于同一类
3,若i和j属于同一类,而j和k属于同一类,则i和k也属于同一类
而只要满足这样的形势,都可以想一想并查集。
假设有6个节点:1,2,3,4,5,6。其中1,3,4是相互连接(或者说属于同一类)的,2和6是相互连接的,5自己一个。
于是这样做并查:
1,一开始自己指向自己:1指向1,2指向2,。。。。
2,这里1和3互相连接,那么就从1和3中随便拿出一个指向另一个,如:令3指向1。
3,重复2,令4指向3;6指向2.
4,从每个集合中任取一个作为代表元素,然后数一下有多少个代表元素就OK了,如:1,3,4中令1为代表元素,2,6中令2为代表元素,5的代表元素是本身,于是1的代表元素是1,3的代表元素是1,4的代表元素是1,2的代表元素是2,6的代表元素是2,5的代表元素是5,一共有3个代表元素。
话说上面第四步是4->3->1,不过因为到头来都是找代办元素,因此改成以1为根节点,4和3作为1的子节点更好,这样下次查找时就可以一下子就找到代表元素了。
于是乎,有时候我们会遇到查找某个元素的代表元素,那直接用下面的代码就可以:
introot = i;
//查找 root
while( root != m_pParent[root] ) {
root= m_pParent[root];
}
//将所有的子结点都直接指向root
intt = i;
intp;
while(t != root ) {
p= m_pParent[t]; // 记录t的父节点
m_pParent[t]= root; // t直接链到root
t= p; // 沿着父节点继续向上找
}
题目
求给定图G的连通分量的数目。如:某国家有N个小岛组成,经过多年的基础设施积累,若干岛屿之间建立了若干桥梁。先重新完善该国的行政区划,规定只要有桥梁连接的岛屿则归属同一个城市(可以通过其他岛屿中转),问该国一共多少个城市?
方法一:深度优先搜索
随便选一个点,搜完后如果有未访问的点就从未访问的点中选一个再搜,重复上述过程。重复了几次就有几个连通分量。方法二:并查集
其实对于该题这样的都可以归为下面这样的形式:1,i和i一定属于同一类
2,若i和j属于同一类,则j和i也属于同一类
3,若i和j属于同一类,而j和k属于同一类,则i和k也属于同一类
而只要满足这样的形势,都可以想一想并查集。
什么是并查集
嗯..这个不太好解释,直接看并查集怎么得出来的会更方便些。假设有6个节点:1,2,3,4,5,6。其中1,3,4是相互连接(或者说属于同一类)的,2和6是相互连接的,5自己一个。
于是这样做并查:
1,一开始自己指向自己:1指向1,2指向2,。。。。
2,这里1和3互相连接,那么就从1和3中随便拿出一个指向另一个,如:令3指向1。
3,重复2,令4指向3;6指向2.
4,从每个集合中任取一个作为代表元素,然后数一下有多少个代表元素就OK了,如:1,3,4中令1为代表元素,2,6中令2为代表元素,5的代表元素是本身,于是1的代表元素是1,3的代表元素是1,4的代表元素是1,2的代表元素是2,6的代表元素是2,5的代表元素是5,一共有3个代表元素。
话说上面第四步是4->3->1,不过因为到头来都是找代办元素,因此改成以1为根节点,4和3作为1的子节点更好,这样下次查找时就可以一下子就找到代表元素了。
于是乎,有时候我们会遇到查找某个元素的代表元素,那直接用下面的代码就可以:
introot = i;
//查找 root
while( root != m_pParent[root] ) {
root= m_pParent[root];
}
//将所有的子结点都直接指向root
intt = i;
intp;
while(t != root ) {
p= m_pParent[t]; // 记录t的父节点
m_pParent[t]= root; // t直接链到root
t= p; // 沿着父节点继续向上找
}
相关文章推荐
- 并查集找连通分量的个数
- POJ 3207 Ikki's Story IV - Panda's Trick 强连通分量或并查集+2sat
- hdu 1241 Oil Deposits 搜索水题,等价于求一个图的连通分量的数目
- csu 1601: War(并查集求每次去掉一条边后连通分量的个数)
- 数据结构实验:连通分量个数(并查集)
- 51nod 1456 小K的技术(Tarjan强连通分量缩点,并查集)
- 连通分量个数(连通分量_并查集)
- LA3644(并查集,维护连通分量的集合)
- hdu1269 运用tarjan算法求有向图中强连通分量数目
- POJ 2236 Wireless Network 【并查集的简单应用 判断是否在同一连通分量】
- hdu 1198 dfs||并查集求连通分量个数,关键建图
- 并查集找连通分量的个数
- 最小生成树MST的Kruskal算法+并查集(链表实现)划分连通分量和集合,并查集可以保存多个集合
- 并查集求连通分量的个数之hdu1213
- 用并查集求解连通分量问题
- 暑假集训 8.17 数据结构实验:连通分量个数(并查集判断连通分量个数 路径压缩)sdutoj1488
- hdu 1198 dfs||并查集求连通分量个数,关键建图
- BZOJ 1854: [Scoi2010]游戏 [连通分量 | 并查集 | 二分图匹配]
- 连通分量个数(并查集的应用)
- POJ 2236 Wireless Network 【并查集的简单应用 判断是否在同一连通分量】