并查集与最小生成树Kruskal算法
一、什么是并查集
在计算机科学中,并查集是一种树型的数据结构,用于处理一些不交集的合并及查询问题。有一个联合-查找算法(union-find algorithm)定义了两个用于次数据结构的操作:
- Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。
- Union:将两个子集合并成一个集合。
二、主要操作
- 初始化:把每个点所在的集合初始化为其自身。
for(int i=1;i<=n;i++)
f[i]=i;
- 查找:查找元素所在的集合,即根节点。
int find(int x)
{
while(f[x]!=x)
x=f[x];
return x;
}
- 合并:将两个元素所在的集合合并为一个集合。
void Union(int x1,int x2)
{
int t1=find(x1);
int t2=find(x2);
if(t1!=t2)
f[t2]=t1;
}
三、优化
上面的代码看似简洁,但是每一次find操作的时间复杂度为O(H),H为树的高度,由于我们没有对树做特殊处理,所以树的不断合并可能会使树严重不平衡,最坏情况每个节点都只有一个子节点。
所以在find函数里采用路径压缩。
int find(int x) //查找x元素所在的集合,回溯时压缩路径
{
if (x != f[x])
{
f[x] = find(f[x]);
//从x结点搜索到祖先结点所经过的结点都指向该祖先结点
}
return f[x];
}
四、模板题
#include<bits/stdc++.h>
using namespace std;
int n,m;
int f[10002];
int find(int x)
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
void Union(int x1,int x2)
{
int t1=find(x1);
int t2=find(x2);
if(t1!=t2) //祖先不一样
f[t2]=t1; //把t2的祖先变为x1的祖先t1
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=0;i<m;i++)
{
int z,x,y;
cin>>z>>x>>y;
if(z==1)
Union(x,y);
else
{
if(find(x)!=find(y))cout<<"N"<<endl;
else cout<<"Y"<<endl;
}
}
return 0;
}
五、最小生成树
一个有n个结点的连通图的生成树是原图的极小联通子图,期包含原图的所有n个结点,且有保持图连通的最少边。
最小生成树其实就是最小权重生成树的简称。
Kruskal算法
- 将图的所有边按照权值从小到大排序
- 遍历所有排好序的边,若构不成回路,则将该边加入到集合中
- 直到找出n-1条边
#include<bits/stdc++.h>
using namespace std;
int n,m;
int s,maxm;
int p[100002];
struct node{
int u;
int v;
int c;
}info[100002];
bool cmp(node x1,node x2)
{
if(x1.c!=x2.c)return x1.c<x2.c;
else if(x1.u!=x2.u) return x1.u<x2.u;
else return x1.v<x2.v;
}
int find(int x) //查找x元素所在的集合,回溯时压缩路径
{
if (x!=p[x])
{
p[x]=find(p[x]);
}
return p[x];
}
void bcj(int x1,int x2)//把x2并入x1的集合
{
int t1,t2;//存储祖先节点
t1=find(x1);
t2=find(x2);
if(t1!=t2)p[t2]=t1;
}
int main()
{
cin>>n>>m;//n就是顶点数,m是边数
for(int i=1;i<=n;i++)
{
p[i]=i;
}
for(int i=0;i<m;i++)
{
cin>>info[i].u>>info[i].v>>info[i].c;
}
sort(info,info+m,cmp);
for(int i=0;i<m;i++)//遍历所有的边
{
if(find(info[i].u)!=find(info[i].v))
{
bcj(info[i].u,info[i].v);//把v并入u的集合
maxm=max(maxm,info[i].c);
}
}
cout<<n-1<<" "<<maxm;
return 0;
}
并查集与最小生成树Kruskal算法的更多相关文章
- hdu 1233(还是畅通project)(prime算法,克鲁斯卡尔算法)(并查集,最小生成树)
还是畅通project Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- POJ-2421Constructing Roads,又是最小生成树,和第八届河南省赛的引水工程惊人的相似,并查集与最小生成树的灵活与能用,水过~~~
Constructing Roads Time Limit: 2000MS Memory Limit: 65536K Description There are N v ...
- 【转】最小生成树——Kruskal算法
[转]最小生成树--Kruskal算法 标签(空格分隔): 算法 本文是转载,原文在最小生成树-Prim算法和Kruskal算法,因为复试的时候只用到Kruskal算法即可,故这里不再涉及Prim算法 ...
- 模板——最小生成树kruskal算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
- POJ 3723 Conscription (Kruskal并查集求最小生成树)
Conscription Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14661 Accepted: 5102 Des ...
- 关于最小生成树(并查集)prime和kruskal
适合对并查集有一定理解的人. 新手可能看不懂吧.... 并查集简单点说就是将相关的2个数字联系起来 比如 房子 1 2 3 4 5 6 ...
- 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数
题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...
- 最小生成树——kruskal算法
kruskal和prim都是解决最小生成树问题,都是选取最小边,但kruskal是通过对所有边按从小到大的顺序排过一次序之后,配合并查集实现的.我们取出一条边,判断如果它的始点和终点属于同一棵树,那么 ...
- 最小生成树 kruskal算法&prim算法
(先更新到这,后面有时间再补,嘤嘤嘤) 今天给大家简单的讲一下最小生成树的问题吧!(ps:本人目前还比较菜,所以最小生成树最后的结果只能输出最小的权值,不能打印最小生成树的路径) 本Tianc在刚学的 ...
随机推荐
- 013——C# chart控件时间作为X轴(附教程)
(一)参考文献:C#之Chart控件系列教程——一 (二)下载地址:https://download.csdn.net/download/xiaoguoge11/11838944 (三)视频教程:ht ...
- 学到了林海峰,武沛齐讲的Day17-5 内置函数
zip print(list(zip(('a','n','c','d'),(1,2,3)))) =====[('a', 1), ('n', 2), ('c', 3)] 一一对应====元组变列表 ...
- python eval的用法
>>>x = >>> eval( '3 * x' ) >>> eval('pow(2,2)') >>> eval('2 + 2' ...
- 适当设置,可以让win10显示更加和自己的意思
一.个性化设置: 1.桌面右击-->个性化-->背景-->图片浏览-->C:\Windows\Web\Screen\img101.png,选择契合度-->适应 2.桌面右 ...
- [信息收集]Nmap命令详解
0x00[介绍] Nmap,也就是Network Mapper,中文为"网络映射器". Nmap是一款开源的网络探测和安全审核的工具,它的设计目标是快速地扫描大型网络. 它是网络管 ...
- Lucene核心数据结构——FST存词典,跳表存倒排或者roarning bitmap 见另外一个文章
Lucene实现倒排表没有使用bitmap,为了效率,lucene使用了一些策略,具体如下:1. 使用FST保存词典,FST可以实现快速的Seek,这种结构在当查询可以表达成自动机时(PrefixQu ...
- Java 方法与数组
方法 什么是方法? 方法定义:方法(Method),函数(function),其实就指一个特定的功能操作,程序中完成独立功能,可重复使用的一段代码的集合. 方法的定义 方法定义格式: [修饰符] 返回 ...
- 感知机模型到DNN模型
参考资料 感知机模型:https://www.cnblogs.com/pinard/p/6042320.html DNN:https://www.cnblogs.com/pinard/p/641866 ...
- C++ STL介绍——简介
目录 1.什么是STL 2.STL中六大组件 2.1 容器(Container) 2.2 迭代器(Iterator) 2.3 算法(Algorithm) 2.4 仿函数(Functor) 2.5 适配 ...
- 梯度下降法(BGD & SGD & Mini-batch SGD)
梯度下降法(Gradient Descent) 优化思想:用当前位置的负梯度方向作为搜索方向,亦即为当前位置下降最快的方向,也称“最速下降法”.越接近目标值时,步长越小,下降越慢. 如下图所示,梯度下 ...