Disjoint Set
生活随笔
收集整理的這篇文章主要介紹了
Disjoint Set
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Disjoint Set,最基本的操作就是 Union 和 Find 兩個函數。
Union 有根據size和rank兩種方法,而 Find 通常使用 path compression 來提升后續搜索的效率。
時間復雜度等可以參考?http://web.eecs.utk.edu/~plank/plank/classes/cs302/Notes/Disjoint/
?
實現一:建立parent數組,這樣做實現起來非常簡單,但是也只適用于集合元素是從0開始自然數(比如一個數組下標)。
Union 根據size合并。
#include <iostream>class DisjointSet{ public:DisjointSet(int size):parent(size,-1){}void Union(int x, int y){int root1=Find(x), root2=Find(y);if (root1==root2) return;// whoever's size is bigger becomes parent of other// notice parent[root] is negative, if parent[root] is smaller, then its size is largerif (parent[root1]>parent[root2]){parent[root2] += parent[root1];parent[root1] = root2;}else{parent[root1] += parent[root2];parent[root2] = root1;}}int Find(int x){if (parent[x]<0) return x;return parent[x] = Find(parent[x]);}private:vector<int> parent; };int main() {DisjointSet s(10);s.Union(2,1);cout << s.Find(1);return 0; }?
實現二:創建一個結構體Node,成員是val和指向parent的指針。相比上一種方法的好處是,val沒有限制。同時需要一個hashmap將val的值映射到Node *,用來找Node。
Union 根據rank合并。
#include <iostream>struct Node{int val;Node *parent;int rank;Node(int v):val(v),parent(this),rank(0){} };class DisjointSet{ public:// Create a set with only one elementvoid makeSet(int val){Node *node=new Node(val);m[val] = node;}// Combines two sets, unions by rankvoid unionSet(int val1, int val2){Node *node1=m[val1];Node *node2=m[val2];Node *root1=findSet(node1);Node *root2=findSet(node2);// they of part of the same set, do nothingif (root1==root2) return;// whoever's rank is higher becomes parent of otherif (root1->rank > root2->rank)root2->parent = root1;else if (root1->rank < root2->rank)root1->parent = root2->parent;else{root1->rank += 1;root2->parent = root1;}}int findSet(int val){return findSet(m[val])->val;}// Find the representative recursively and does path compression as wellNode *findSet(Node *node){Node *parent=node->parent;if (parent==node) return node;node->parent = findSet(node->parent);return node->parent;}private:unordered_map<int,Node *> m; // node val -> Node * };int main(){DisjointSet a;for (int i=1;i<=7;++i) a.makeSet(i);a.unionSet(1,2);a.unionSet(2,3);cout << a.findSet(1) << endl;cout << a.findSet(3) << endl;cout << a.findSet(7) << endl;return 0; }?
應用中,可以簡化Union,不用根據size,rank合并,直接把一個節點的root賦為另一個節點root的父親即可。
?
轉載于:https://www.cnblogs.com/hankunyan/p/9998626.html
總結
以上是生活随笔為你收集整理的Disjoint Set的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【2018年11月21日】煤炭行业的估值
- 下一篇: android studio代码对齐的快