日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Disjoint Set

發布時間:2025/3/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。