并查集
并查集
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。常常在使用中以森林来表示。
操作:
- 将两个集合合并。
- 询问两个元素是否在一个集合中。
基本原理:
每个集合用一棵树来表示。树根的编号就是整个集合的编号。每个节点的值储存它的父节点编号,
问题:
while (p[x] != x) x = p[x]
求得。即当
重要优化:路径压缩
在上面的
这里需要利用递归实现。
int find(int x)
{
return x == p[x] ? p[x] : p[x] = find(p[x]);
}
例题:带货援助
题目描述
张三学姐找人帮忙带货。有
请你可以帮她算一下最少可以只花多少钱就可以让所有带货达人都帮忙带货。
输入格式
第一行包含两个整数
第二行包含
接下来的
输出格式
输出一个数,表示张三学姐雇佣所有带货达人的最少金钱。
输入输出样例
输入 | 输出 |
---|---|
5 2 2 5 3 5 9 1 4 4 5 |
10 |
10 0 1 2 3 4 5 6 7 8 9 10 |
55 |
10 5 1 6 2 7 3 8 4 9 5 10 1 2 3 4 5 6 7 8 9 10 |
15 |
分析:
按照题意,我们需要将是朋友的带货达人放在一个集合里,并且只需要花费这个集合里所需的最小的价值就能让这个集合所有的带货达人帮忙带货,对于没有朋友关系的带货达人,则只能花费相应的金钱让他帮忙带货。
所以我们用并查集,先将有朋友关系的带货达人的编号放进同一个集合,同时,我们可以把根节点的值变为其中最小的那个价值。最后,我们遍历所有的集合,求根节点的价值之和。(单独的带货达人,根节点就是他自己的编号)
#include <iostream>
using namespace std;
const int N = 1e5+10;
int a[N], p[N];
int find(int x)
{
return x == p[x] ? p[x] : p[x] = find(p[x]);
}
int main()
{
int n, m;
cin >> n >> m;
for (int i=1;i<=n;i++) p[i] = i; //初始化根节点的值
for (int i=1;i<=n;i++) cin >>a[i];
while (m--)
{
int x, y;
cin >> x>> y;
if (find(x) != find(y))
{
if (a[find(x)] > a[find(y)]) p[find(x)] = find(y); //集合合并操作,让需要金钱更多的带货达人的根节点变为需要金钱更少的带货达人
else p[find(y)] = find(x);
}
}
long long ans = 0;
for (int i=1;i<=n;i++)
{
if (p[i] == i) ans += a[i];
}
cout << ans << endl;
}
原题链接:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App