并查集与最小生成树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在刚学的 ...
随机推荐
- python AES对称加密
1.首先需要安装第三方库 pip install pycryptodome 2.实例代码,亲测可用 # coding:utf-8 import base64 from Crypto.Cipher im ...
- 55、servlet3.0-ServletContext注册三大组件
55.servlet3.0-ServletContext注册三大组件 使用ServletContext 注册 Servlet.Filter.Listener 使用编码的方式,在项目启动的时候给 Ser ...
- JAVA的循环结构进阶
1.什么是二重循环: 一个循环体内又包含另一个完整的循环结构 语法: ...
- MongoDB 建立与删除索引
1.1 在独立服务器上面建立索引 在独立服务器上面创建索引,可以在空闲时间于后台建立索引. 在后台建立索引,可利用background:true参数运行 >db.foo.ensureIndex( ...
- 后缀数组 TYVJ P1860 后缀数组
/*P1860 后缀数组时间: 1000ms / 空间: 131072KiB / Java类名: Main描述 我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子 ...
- P1213 时钟
题目描述 考虑将如此安排在一个 3 x 3 行列中的九个时钟: 目标要找一个最小的移动顺序将所有的指针指向12点.下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动.选择1到9号移动方法 ...
- pandas 筛选某一列最大值最小值 sort_values、groupby、max、min
高效方法: dfs[dfs['delta'].isnull()==False].sort_values(by='delta', ascending=True).groupby('Call_Number ...
- Fidller抓包分析post请求
目的:抓包是为了最近做接口测试做准备,以前没有用过这个工具,最近来学下,但是网上很多文章了,所以不一一记录,有一部分参考即可 1.如何抓取想要的web端或者手机端包,已经有很多文章谢了,推荐的参考文章 ...
- [luogu P1527]矩阵乘法(矩形k小)
传送门 Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Solution 整体二分 练习一波... 就是一堆询问放在一起二分 另外的,第一次发现原来矩 ...
- hbase单点安装
系统环境:centos 6 软件包: hbase版本:hbase-1.4.8-bin.tar.gz 下载地址:wget http://mirror.bit.edu.cn/apache/hba ...