/* Union-Find algorithm. Ref: Sedgwick, Chap 30, pg 441 */ #include const MAXSIZE = 1000; typedef int Element; typedef Element Set; class UF_DisjointSets { public: UF_DisjointSets(int size) // Constructor. Initially Elements 0 thru size-1 each is a set of one. ; Set Find(Element x) // Returns the set (actually the root element of the set) // currently containing x. ; bool Same_Set_p(Element x, Element y) // Returns true iff x and y currently are in the same set. { return Find(x) == Find(y); } void Union(Element x, Element y) // Merge the set containing x and the set containing y into one. ; private: Element* parent; inline bool is_root(Element x) { return parent[x] < 0; } inline int size(Element x) { return -parent[x] ; } /* convention: parent[x] >= 0 means parent[x] is the parent of x in the tree which represents the set currently containing x. parent[x] < 0 means x is the root of the tree representing the set which contains x, and -parent[x] (a positive number) is the number of elements in that set. */ }; UF_DisjointSets::UF_DisjointSets(int size) /* constructor. initially elements 0 thru size-1 each is a set of one. */ { parent = new(int[size]); for (int i = 0; i < size; i++) parent[i] = -1; } Set UF_DisjointSets::Find(Element x) /* returns the set (actually the root element) of the set currently containing x */ { /** Basic version of Find ** return parent[x] < 0 ? x : Find(parent[x]; */ /** Find with path compression for better performance **/ return parent[x] < 0 ? x : parent[x] = Find(parent[x]); } void UF_DisjointSets::Union(Element x, Element y) /* merge the set containing x and the set containing y into one */ { Set i = Find(x); Set j = Find(y); /** Basic version of Union ** parent[j] = i; */ /** Union with weight balancing for better performance **/ if (parent[i] < parent[j]) { /* set i had more elements so keep it at root */ parent[i] += parent[j]; parent[j] = i; } else { /* set j had more elements so keep it at root */ parent[j] += parent[i]; parent[i] = j; } }