[算法笔记]带权并查集
带权并查集是普通并查集的进阶版本,功能更加强大。
普通并查集只能判断两个元素是否在一个集合中,带权并查集可以维护集合元素之间的关系,这个关系由每个元素的权值维护。
对权值的维护,我们需要在find(),unite()操作中分别进行修改。
class UnionFind { public: unordered_map<string, string> p; unordered_map<string, double> d; UnionFind(vector<vector<string>>& equations, vector<double>& values) { for (int i = 0; i < values.size(); i++) { string a = equations[i][0], b = equations[i][1]; // 可能某个结点多次出现,防止对其初始化,导致覆盖 if (!p.count(a)) { p[a] = a; d[a] = 1; } if (!p.count(b)) { p[b] = b; d[b] = 1 ; } unite(a, b, values[i]); } } string find(string x) { if (x != p[x]) { auto t = find(p[x]); d[x] *= d[p[x]]; p[x] = t; } return p[x]; } void unite(string a, string b, double v) { string ra = find(a), rb = find(b); if (ra != rb) { p[ra] = rb; d[ra] = v * d[b] / d[a]; } } };
初始化:a, b是两个需要合并的结点,v是它们的值,a,b满足一个关系式,即。
find():
我们同样进行路径压缩,路径压缩实际上就是将结点x,跳过x的父结点等等,直接与x的根结点相连。普通并查集我们可以直接相连,但是带权并查集我们需要维护结点权值。

如图,的权值就等于,类似于带权有向图,我们要保证的距离不变,换句话说,维护了的路径权值和。
unite:
普通并查集中我们只要:
x = find(x), y = find(y); p[x] = y;
带权并查集中:考虑。
结点x,y可能有多种情况,可能。
我们直接考虑最复杂的情况,即,这种情况是最复杂的,其他情况都是该情况的特殊情况!

观察图可得,蓝色线代表权值v(蓝色线不会相连,这里只是做出显示),为了维护 四边形法则(也就是X->Y无论从那条路径走,路径权值和应该相等),我们可以求得 。
分类:
算法总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)