并查集--第1篇
学习并查集,这是第1篇,后续会继续补上若干文章。
先看代码:
#include <iostream> #include <vector> using namespace std; class UnionFind { private: int count; //连通分量个数 vector<int> parent; //存储每个结点的父节点 vector<int> size; // 记录每棵树的“重量” public: UnionFind(int n) { count = n; parent.resize(n+1, 1); size.resize(n+1, 1); for (int i = 0; i <= n; ++i) { parent[i] = i; size[i] = 1; } } int Find(int x) { // 路径压缩,方法1 while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; } return x; // 路径压缩,方法2 //return parent[x] == x ? x : parent = find(parent[x]); } void Union(int p, int q) { int rootP = Find(p); int rootQ = Find(q); if (rootP == rootQ) { return; } //小树接到大树下面,较平衡 if (size[rootP] > size[rootQ]) { parent[rootQ] = rootP; size[rootP] += size[rootQ]; } else { parent[rootP] = rootQ; size[rootQ] += size[rootP]; } count--; } bool connected(int p, int q) { int rootP = Find(p); int rootQ = Find(q); return rootP == rootQ; } void printParent() { cout << "print parent:" << endl; for (auto val : parent) { cout << val << ","; } cout << endl << endl; } }; int main() { vector<vector<int>> arrInput; vector<int> oneItem; oneItem.clear(); oneItem.emplace_back(1); oneItem.emplace_back(2); arrInput.emplace_back(oneItem); oneItem.clear(); oneItem.emplace_back(2); oneItem.emplace_back(3); arrInput.emplace_back(oneItem); oneItem.clear(); oneItem.emplace_back(3); oneItem.emplace_back(4); arrInput.emplace_back(oneItem); oneItem.clear(); oneItem.emplace_back(1); oneItem.emplace_back(4); arrInput.emplace_back(oneItem); oneItem.clear(); oneItem.emplace_back(1); oneItem.emplace_back(5); arrInput.emplace_back(oneItem); int n = arrInput.size(); UnionFind ufd(n); for (auto& edge : arrInput) { int node1 = edge[0], node2 = edge[1]; cout << "======= for find start("<<node1<<","<<node2<<")==========" << endl; if (ufd.Find(edge[0]) != ufd.Find(edge[1])) { cout <<"========= for Find ======="<<endl; ufd.printParent(); ufd.Union(node1, node2); } else { cout << "END ----- edge:"<< endl;; ufd.printParent(); system("PAUSE"); return 0; } } system("PAUSE"); return 0; }
======= for find start(1,2)========== ========= for Find ======= print parent: 0,1,2,3,4,5, ======= for find start(2,3)========== ========= for Find ======= print parent: 0,2,2,3,4,5, ======= for find start(3,4)========== ========= for Find ======= print parent: 0,2,2,2,4,5, ======= for find start(1,4)========== END ----- edge: print parent: 0,2,2,2,2,5,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?