并查集与最小生成树(Kruskal算法)

并查集

什么是“并查集”?

可以这么理解,并查集就是查询两个元素之间有没有什么关联,就像一个家族,你兄弟姐妹的亲戚可以算做你亲戚。

并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。

顾名思义,并查集支持两种操作:

  • 合并(Union):合并两个元素所属集合(合并对应的树)
  • 查询(Find):查询某个元素所属集合(查询对应的树的根节点),这可以用于判断两个元素是否属于同一集合

并查集在经过修改后可以支持单个元素的删除、移动;使用动态开点线段树还可以实现可持久化并查集。(摘自OI WIKI)

并查集(easy.ver)的实现包含几个个步骤:

1.初始化数组

并查集通过构建一个一维数组来实现,本质上是维护一个森林。我们先定义出一个一维数组f[N](其中N代表森林中元素个数)用来存放每一棵树的编号。一开始的时候每一棵树都是一个独立的集合。

代码实现如下:

for(int i=1;i<=n;i++) {
        f[i] = i;
}

2.查询(Find)

我们需要沿着树向上移动,如果上一级是其父节点,则函数会继续进行查询,直至找到根节点(即祖宗节点)。

代码实现如下:

int find(int x) {
    if (f[x]!=x) {
        return f[x]=find(f[x]);
    }
    return f[x];
}

3.合并(Union)

我们由上一步查询可得知相对应的集合的祖宗节点(即根节点),我们只需要将这两个集合的祖父节点相连即可。 代码实现如下:

void union(){
    f[find(b)] = find(f[a]);
}

这就是并查集的简单的实现过程(一般不会超时吧)。如果遇到数据量巨大的时候,我们可以对查询与合并进行优化,这是后话了。

洛谷p3367【模板】并查集

题目描述

如题,现在有一个并查集,你需要完成合并和查询操作。

输入格式

第一行包含两个整数 ,表示共有 个元素和 个操作。

接下来 行,每行包含三个整数

时,将 所在的集合合并。

时,输出 是否在同一集合内,是的输出 Y ;否则输出 N

输出格式

对于每一个 的操作,都有一行输出,每行包含一个大写字母,为 Y 或者 N

样例 #1

样例输入 #1

4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4

样例输出 #1

N
Y
N
Y

提示

对于 的数据,

对于 的数据,

对于 的数据,

AC code:

//And in that light,I'll find deliverance;;
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
const int N = 2e5 + 10;
int op;
ll f[N];

int find(int x) {
    if ( f[x] != x ) {
        return f[x] = find(f[x]);
    }
    return f[x];
}
int n, q;
int a, b;

void solve() {
    if (op == 1) {
        f[find(b)] = find(f[a]);
    }
    if (op == 2) {
        if (find(a) == find(b))
            cout << "Y" << endl;
        else
            cout << "N" << endl;
    }
}

int main() {
    IOS;
    cin >> n >> q;

    for (int i = 1; i <= n; i++) {
        f[i] = i;
    }
    while (q--) {
        cin >> op >> a >> b;
        solve();
    }
    return 0;


}

最小生成树

最小生成树有两种算法,一种是Prim算法,还有一种是Kruskal算法。

Prim算法:

Kruskal算法:

全部评论

相关推荐

10-19 10:28
已编辑
西南石油大学 后端工程师
团孝子已上线feeling:面了很多家公司,能感受到目前只有小公司+外包喜欢问八股。大厂虽然也问八股,但是是从实习、项目中进行提问,并且大厂会问很深,面试官也会对你的回答进行思考➕追问,所以准备大厂面试前一定要备好相关资料。对于算法,我做的是codetop前100+力扣hot100+力扣高频150,面试中实感hot100就足够,基本上只要是hot100就秒答。对于项目和八股,我做的也是烂大街的星球项目,八股则是看小林和问ai,自己也写了很多技术博客和画了很多思维导图,并且自己也尝试用嘴巴说出来,不只停留于纸面。运气也很重要,必须要让面试官/HR看到简历才行,所以建议投递时间是下午两点。tl:第一岗位9.9&nbsp;投递9.10&nbsp;一面(一面评价:最近见过最强的大三,结束五分钟后约二面,都晚上九点了不下班吗)9.11&nbsp;二面(三道算法a出两道,反问评价:经验不够等横向,我实习生要啥经验)9.21挂(实习时间过短+其他原因,想要一年实习的,为什么不招个正职)第二岗位10.10投递10.11约面(主管打电话,说看到我之前投递记录了想要我挂qa职进去干后端,同意)10.14&nbsp;一面(无八股,主动说确实很强,意愿很强)10.16&nbsp;oc其余,友邦,东软,东华,惠择,用友oc已拒京东测开一面挂(投后端被测开捞)腾讯测试已拒(投后端被测开捞)ps:表扬惠择的主管面,没怎么问技术(可能是一面面试官沟通过了),全程一起讲大道理,解答了心中很多疑惑,也告诉我以面试官角度来看怎么选候选人,如果可以下次一定选惠择
HeaoDng:美团好像可以触发一面通
点赞 评论 收藏
分享
10-22 20:17
已编辑
门头沟学院 Python
敢逐云霄志:后端没92学历+大厂实习基本别想在秋招约面了,笔试可能都不会给你发,我双非本3段实习,一大,中,一小,中大厂笔试做了一堆,大厂就只有字节给面,其他全没动静,根本轮不到双非。
你觉得第一学历对求职有影...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务