当前位置: 首页 > news >正文

20251206 - 并查集

20251206 - 并查集总结

如果要求出两个东西是否在集合里,怎么办?

把它存在图里,再离线处理。

Tarjan 巨佬提出了并查集。

查找

如果要判断两个人是否是同一个省的人,可以问问你们的代表人物是谁?

如果相同,就是同一个省的。

所以,记录每一个元素的父亲,再每次向上找即可。

递归版:

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

迭代版:

int find(x) {while (fa[x] != x) {x = fa[x];}return x;
}

合并

合并时,找到两个集合的代表元,把一个集合的代表元改到另一个即可。

void unite(int x, int y) {x = find(x), y = find(y);if (x != y) fa[x] = y;
}

优化

优化1:启发式合并

如果不优化,时间复杂度可能会飙到 \(O(n)\),就像可怜的二叉搜索树一样,怎么优化呢?平衡树

可以把子树节点少的连向节点多的,这样子,树高可以稳定在 \(\log_2 n\)

期望复杂度:\(O(\log_2 n)\)

优化2:路径压缩

我们只要知道代表元,我们可以将父亲直接连向代表元,这是非常大的优化,可以从 \(O(\log_2 n)\) 优化到 \(O(α(n))\)\(α\) 是阿克曼反函数,可以当作不超过 \(4\) 的常数。

代码:

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

时间复杂度

优化1:启发式合并

期望复杂度:\(O(\log_2 n)\)

实际复杂度:不知道。

优化2:路径压缩

期望复杂度:\(O(α(n))\)

实际复杂度:不知道。

题外话

Tarjan 巨佬说:"如果不用启发式合并,只用路径压缩,时间复杂度最坏也是 \(O(\log_2 n)\),但均摊 \(O(α(n))\)。"

例题:

1. 并查集

int find(int x) {if (fa[x] == x) return x;return fa[x] = find(fa[x]);
}
void unite(int x, int y) {x = find(x), y = find(y);if (x != y) {fa[x] = y;}
}
void solve() {n = read(), m = read();for (int i = 1; i <= n; i++) fa[i] = i;while (m--) {int op, x, y;op = read(), x = read(), y = read();if (op == 1) {unite(x, y);}else {printf("%c\n", find(x) == find(y) ? 'Y' : 'N');}}
}

2.资料分发 1

就是求连通分量个数。

void solve() {n = read(), m = read();for (int i = 1; i <= n; i++) fa[i] = i;for (int i = 1; i <= m; i++) {int x, y;x = read(), y = read();unite(x, y);}int res = 0;for (int i = 1; i <= n; i++)res += fa[i] == i;printf("%d\n", res); return 0;
}

3.连通图

就是求连通分量个数。

void solve() {n = read(), m = read();for (int i = 1; i <= n; i++) fa[i] = i;for (int i = 1; i <= m; i++) {int x, y;x = read(), y = read();unite(x, y);}int res = 0;for (int i = 1; i <= n; i++)res += fa[i] == i;printf("%d\n", res - 1); return 0;
}

4.朋友

map 来搞并查集。

map<int, int>fa;
int find(int x) {if (fa[x] == x) return x;return fa[x] = find(fa[x]);
}
void unite(int x, int y) {x = find(x), y = find(y);if (x != y) {fa[x] = y;}
}
int main() {n = read(), m = read(), P = read(), Q = read();for (int i = -m; i <= n; i++) {fa[i] = i;}while (P--) {int x, y;x = read(), y = read();unite(x, y);}while (Q--) {int x, y;x = read(), y = read();unite(x, y);}int ans1 = 0, ans2 = 0;for (int i = -m; i <= -1; i++) {if (find(-1) == find(fa[i])) ans1++;}for (int i = 1; i <= n; i++)if (find(1) == find(fa[i])) ans2++;printf("%d\n", min(ans1, ans2));return 0;
}

5.营救

怎么这么像最小生成树呢?

int fa[N];
int find(int x) {if (fa[x] == x) return x;return fa[x] = find(fa[x]);
}
void unite(int x, int y) {x = find(x), y = find(y);if (x != y) {fa[x] = y;}
}
int n, m, s, t;
vector<array<int, 3>> edges;
int main() {n = read(), m = read(), s = read(), t = read();edges.resize(m);for (int i = 0; i < m; i++) {scanf("%d%d%d", &edges[i][1], &edges[i][2], &edges[i][0]);}for (int i = 1; i <= n; i++) fa[i] = i;sort(edges.begin(), edges.end());for (auto [w, x, y] : edges) {int l = find(x), r = find(y);if (l != r)fa[l] = r;if (find(s) == find(t)) {printf("%d\n", w);return 0;}}return 0;
}

6. 炸铁路

暴力的没边了。

struct node {int u, v;
} e[N];
vector<pair<int, int>> ans;
int fa[N];
int find(int x) {if (fa[x] == x) return x;return fa[x] = find(fa[x]);
}
void unite(int x, int y) {x = find(x), y = find(y);if (x != y) {fa[x] = y;}
}
void solve(int x) {for (int i = 1; i <= n; i++) fa[i] = i;for (int i = 1; i <= m; i++) {if (i != x) {unite(e[i].u, e[i].v);}}for (int i = 1; i <= n; i++) {for (int j = i + 1; j <= n; j++) {if (find(i) != find(j)) {ans.pb({e[x].u, e[x].v});return;}}}
}
int main() {n = read(), m = read();for (int i = 1; i <= m; i++) {int a, b;a = read(), b = read();e[++idx] = {a, b};}for (int i = 1; i <= m; i++) {solve(i);}sort(ans.begin(), ans.end());for (auto [x, y] : ans) {if (x > y) swap(x, y);printf("%d %d\n", x, y);}return 0;
}
http://www.jsqmd.com/news/65154/

相关文章:

  • Microsoft Visual Studio 2010 TFS强制解除签出
  • HTTP/2在EDI领域中的优势:构建高效、安全、现代化的数据交换基石 - 详解
  • Springboot智慧旅游管理系统6w63eon8(软件+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • why Picograph can not learn English by translator
  • 【EF Core】“DB First”方案下用编程方式生成数据库模型代码
  • 面向AI时代的操作系统:openEuler在WSL环境下的高效开发实践
  • cursor
  • 树的重心及dfs
  • 详细介绍:如何进行AI作图(架构图,流程图等)
  • 2025年进口地板十大品牌综合实力榜:聚焦高端家居与智能化未来
  • openEuler 软件生态多元适配评测:分布式存储与大数据组件实战验证
  • 2025 最新机器视觉检测服务商 / 厂家 TOP5 评测!智能检测赋能制造升级,权威榜单助力企业选型,智慧工厂设计、建设及管理解决方案
  • 短视频矩阵架构搭建指南:源码部署与全流程解析
  • 2025年中国五大铝氧化着色生产企业推荐,看哪家工艺水平高
  • 2025年12月中国GEO服务商综合推荐分析:摘星AI引领全球
  • 揭秘WAAP:现代Web应用与API保护的四大核心安全支柱
  • Java基础学习知识点笔记
  • 深入解析:从阿里云大模型服务平台百炼看AI应用集成与实践
  • 完整教程:Docker学习笔记---day001
  • AI搜索排名优化公司推荐:解锁智能时代曝光与转化新密码
  • 2025年中国气力输送厂五大推荐,看哪家技术实力强
  • 2025年国内GEO(AI搜索优化)营销公司推荐排行榜分析:摘星ai引领行业智造
  • 在 S2S 场景中理解 On-Behalf-Of (OBO) 流程
  • 2025 年 12 月苏作红木家具品牌匠心推荐榜:东方雅韵与传世工艺的收藏级甄选
  • .NET Core WebAPI 中使用 MISE + S2S 的三种方式
  • NetCore使用WCF简单方式
  • 2025年无锡上料机靠谱厂家推荐:看哪家技术实力强?
  • 2025年度靠谱的实验室反应釜厂家TOP5权威推荐
  • 基于Python+Vue开发的婚恋交友管理系统源码+运行步骤+计算机专业
  • 2025-12-07 GitHub 热点项目精选