// Add the fact that v1 and v2 are equivalent // return true if v1 was not already equivalent to v2 // and false if v1 was already equivalent to v2 bool SetEquivalent(int v1, int v2) { bool const already_equiv = false; if (v1 == v2) return already_equiv; ensureElementExists(v1); ensureElementExists(v2); const int r1 = disjoint_sets_.find_set(v1); const int r2 = disjoint_sets_.find_set(v2); if (r1 == r2) return already_equiv; root_set_map_t::const_iterator it1 = rootSetMap_.find(r1); assert(it1 != rootSetMap_.end()); std::list<int> s1 = it1->second; root_set_map_t::const_iterator it2 = rootSetMap_.find(r2); assert(it2 != rootSetMap_.end()); std::list<int> s2 = it2->second; s1.splice(s1.begin(), s2); // union the related sets disjoint_sets_.link(r1, r2); // union the disjoint sets // associate the combined related set with the new root int const new_root = disjoint_sets_.find_set(v1); if (new_root != r1) { rootSetMap_.erase(it1); } else { rootSetMap_.erase(it2); } rootSetMap_[new_root] = s1; return !already_equiv; }
// Return true if v1 and v2 are equivalent bool AreEquivalent(int v1, int v2) const { if (v1 == v2) { return true; } // The element does not exist, so we do not // know any equivalence information, // hence, v1 and v2 are not equivalent. if (!elementExists(v1) || !elementExists(v2)) { return false; } return disjoint_sets_.find_set(v1) == disjoint_sets_.find_set(v2); }
void __output_ancestors(Vertex from, Vertex const u, Vertex const v) { sets.make_set(from); ancestors[sets.find_set(from)] = from; VertexContainer child = children(from); for (VertexContainer::iterator ite = child.begin(); ite != child.end(); ++ite) { __output_ancestors(*ite, u, v); sets.union_set(from, *ite); ancestors[sets.find_set(from)] = from; } colors[from] = black; if (u == from && colors[v] == black) { printf("The least common ancestor of %d and %d is %d.\n", query_dat(u), query_dat(v), query_dat(ancestors[sets.find_set(v)])); } else if (v == from && colors[u] == black) { printf("The least common ancestor of %d and %d is %d.\n", query_dat(v), query_dat(u), query_dat(ancestors[sets.find_set(u)])); } }
// Return the representative for the node v. int FindSet(int v) const { // If element does not exist if (!elementExists(v)) { // Then it is its own root. // This avoids adding singleton sets to the partition. return v; } return disjoint_sets_.find_set(v); }
// Return a list of elements that are in the same disjoint set // as v. std::list<int> GetRelatedSet(int v) const { std::list<int> ret; if (!elementExists(v)) { ret.push_back(v); return ret; } int root = disjoint_sets_.find_set(v); root_set_map_t::const_iterator it = rootSetMap_.find(root); assert(it!=rootSetMap_.end()); return it->second; }