学习并查集,这是第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,