Demos and benchmarks are not built by default now. They can be enabled with the --enable-demo and --enable-benchmark configure flags.
2 * lemon/unionfind.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_UNION_FIND_H
18 #define LEMON_UNION_FIND_H
22 //!\brief Union-Find data structures.
30 #include <lemon/invalid.h>
34 //! \addtogroup auxdat
38 * \brief A \e Union-Find data structure implementation
40 * The class implements the \e Union-Find data structure.
41 * The union operation uses rank heuristic, while
42 * the find operation uses path compression.
43 * This is a very simple but efficient implementation, providing
44 * only four methods: join (union), find, insert and size.
45 * For more features see the \ref UnionFindEnum class.
47 * It is primarily used in Kruskal algorithm for finding minimal
48 * cost spanning tree in a graph.
51 * \pre The elements are automatically added only if the map
52 * given to the constructor was filled with -1's. Otherwise you
53 * need to add all the elements by the \ref insert() method.
54 * \bug It is not clear what the constructor parameter is used for.
57 template <typename T, typename TIntMap>
61 typedef T ElementType;
62 typedef std::pair<int,int> PairType;
65 std::vector<PairType> data;
69 UnionFind(TIntMap& m) : map(m) {}
72 * \brief Returns the index of the element's component.
74 * The method returns the index of the element's component.
75 * This is an integer between zero and the number of inserted elements.
86 while ( (next = data[comp].first) != comp) {
89 while ( (next = data[comp0].first) != comp) {
90 data[comp0].first = comp;
98 * \brief Inserts a new element into the structure.
100 * This method inserts a new element into the data structure.
102 * It is not required to use this method:
103 * if the map given to the constructor was filled
104 * with -1's then it is called automatically
105 * on the first \ref find or \ref join.
107 * The method returns the index of the new component.
113 data.push_back(std::make_pair(n, 1));
119 * \brief Joining the components of element \e a and element \e b.
121 * This is the \e union operation of the Union-Find structure.
122 * Joins the component of element \e a and component of
123 * element \e b. If \e a and \e b are in the same component then
124 * it returns false otherwise it returns true.
135 if ( data[ca].second > data[cb].second ) {
137 data[ca].second += data[cb].second;
141 data[cb].second += data[ca].second;
147 * \brief Returns the size of the component of element \e a.
149 * Returns the size of the component of element \e a.
155 return data[ca].second;
163 /*******************************************************/
166 #ifdef DEVELOPMENT_DOCS
169 * \brief The auxiliary class for the \ref UnionFindEnum class.
171 * In the \ref UnionFindEnum class all components are represented as
173 * Items of these lists are UnionFindEnumItem structures.
175 * The class has four fields:
176 * - T me - the actual element
177 * - IIter parent - the parent of the element in the union-find structure
178 * - int size - the size of the component of the element.
179 * Only valid if the element
180 * is the leader of the component.
181 * - CIter my_class - pointer into the list of components
182 * pointing to the component of the element.
183 * Only valid if the element is the leader of the component.
188 template <typename T>
189 struct UnionFindEnumItem {
191 typedef std::list<UnionFindEnumItem> ItemList;
192 typedef std::list<ItemList> ClassList;
193 typedef typename ItemList::iterator IIter;
194 typedef typename ClassList::iterator CIter;
201 UnionFindEnumItem() {}
202 UnionFindEnumItem(const T &_me, CIter _my_class):
203 me(_me), size(1), my_class(_my_class) {}
208 * \brief A \e Union-Find data structure implementation which
209 * is able to enumerate the components.
211 * The class implements a \e Union-Find data structure
212 * which is able to enumerate the components and the items in
213 * a component. If you don't need this feature then perhaps it's
214 * better to use the \ref UnionFind class which is more efficient.
216 * The union operation uses rank heuristic, while
217 * the find operation uses path compression.
220 * need to add all the elements by the \ref insert() method.
224 template <typename T, template <typename Item> class Map>
225 class UnionFindEnum {
227 typedef std::list<UnionFindEnumItem<T> > ItemList;
228 typedef std::list<ItemList> ClassList;
229 typedef typename ItemList::iterator IIter;
230 typedef typename ItemList::const_iterator IcIter;
231 typedef typename ClassList::iterator CIter;
232 typedef typename ClassList::const_iterator CcIter;
235 typedef T ElementType;
236 typedef UnionFindEnumItem<T> ItemType;
237 typedef Map< IIter > MapType;
243 IIter _find(IIter a) const {
246 while( (next = comp->parent) != comp ) {
251 while( (next = comp1->parent) != comp ) {
252 comp1->parent = comp->parent;
259 UnionFindEnum(MapType& _m) : m(_m) {}
263 * \brief Inserts the given element into a new component.
265 * This method creates a new component consisting only of the
269 void insert(const T &a)
273 classes.push_back(ItemList());
274 CIter aclass = classes.end();
277 ItemList &alist = *aclass;
278 alist.push_back(ItemType(a, aclass));
279 IIter ai = alist.begin();
287 * \brief Inserts the given element into the component of the others.
289 * This methods inserts the element \e a into the component of the
293 void insert(const T &a, const T &comp) {
295 IIter clit = _find(m[comp]);
296 ItemList &c = *clit->my_class;
297 c.push_back(ItemType(a,0));
307 * \brief Finds the leader of the component of the given element.
309 * The method returns the leader of the component of the given element.
312 T find(const T &a) const {
313 return _find(m[a])->me;
318 * \brief Joining the component of element \e a and element \e b.
320 * This is the \e union operation of the Union-Find structure.
321 * Joins the component of element \e a and component of
322 * element \e b. If \e a and \e b are in the same component then
323 * returns false else returns true.
326 bool join(T a, T b) {
328 IIter ca = _find(m[a]);
329 IIter cb = _find(m[b]);
335 if ( ca->size > cb->size ) {
337 cb->parent = ca->parent;
338 ca->size += cb->size;
340 ItemList &alist = *ca->my_class;
341 alist.splice(alist.end(),*cb->my_class);
343 classes.erase(cb->my_class);
348 ca->parent = cb->parent;
349 cb->size += ca->size;
351 ItemList &blist = *cb->my_class;
352 blist.splice(blist.end(),*ca->my_class);
354 classes.erase(ca->my_class);
363 * \brief Returns the size of the component of element \e a.
365 * Returns the size of the component of element \e a.
368 int size(const T &a) const {
369 return _find(m[a])->size;
374 * \brief Splits up the component of the element.
376 * Splitting the component of the element into sigleton
377 * components (component of size one).
380 void split(const T &a) {
382 IIter ca = _find(m[a]);
387 CIter aclass = ca->my_class;
389 for(IIter curr = ca; ++curr != aclass->end(); curr=ca) {
390 classes.push_back(ItemList());
391 CIter nl = --classes.end();
392 nl->splice(nl->end(), *aclass, curr);
405 * \brief Sets the given element to the leader element of its component.
407 * Sets the given element to the leader element of its component.
410 void makeRep(const T &a) {
413 IIter la = _find(ia);
414 if (la == ia) return;
416 ia->my_class = la->my_class;
421 CIter l = ia->my_class;
422 l->splice(l->begin(),*l,ia);
429 * \brief Moves the given element to an other component.
431 * This method moves the element \e a from its component
432 * to the component of \e comp.
433 * If \e a and \e comp are in the same component then
434 * it returns false otherwise it returns true.
437 bool move(const T &a, const T &comp) {
440 IIter lai = _find(ai);
441 IIter clit = _find(m[comp]);
446 ItemList &cl = *clit->my_class,
447 &al = *lai->my_class;
449 bool is_leader = (lai == ai);
450 bool singleton = false;
456 cl.splice(cl.end(), al, ai);
460 classes.erase(ai->my_class);
464 lai->size = ai->size;
465 lai->my_class = ai->my_class;
469 for (IIter i = lai; i != al.end(); ++i)
483 * \brief Removes the given element from the structure.
485 * Removes the given element from the structure.
487 * Removes the element from its component and if the component becomes
488 * empty then removes that component from the component list.
490 void erase(const T &a) {
495 IIter la = _find(ma);
497 if (ma -> size == 1){
498 classes.erase(ma->my_class);
504 la->my_class = ma->my_class;
507 for (IIter i = la; i != la->my_class->end(); ++i) {
512 la->my_class->erase(ma);
517 * \brief Removes the component of the given element from the structure.
519 * Removes the component of the given element from the structure.
522 void eraseClass(const T &a) {
526 CIter c = _find(ma)->my_class;
527 for (IIter i=c->begin(); i!=c->end(); ++i)
530 classes.erase(_find(ma)->my_class);
535 friend class UnionFindEnum;
539 ClassIt(Invalid): i(0) {}
542 operator const T& () const {
543 ItemList const &ll = *i;
544 return (ll.begin())->me; }
545 bool operator == (ClassIt it) const {
548 bool operator != (ClassIt it) const {
551 bool operator < (ClassIt it) const {
555 bool valid() const { return i != 0; }
557 void first(const ClassList &l) { i = l.begin(); validate(l); }
558 void next(const ClassList &l) {
562 void validate(const ClassList &l) {
569 * \brief Sets the iterator to point to the first component.
571 * Sets the iterator to point to the first component.
573 * With the \ref first, \ref valid and \ref next methods you can
574 * iterate through the components. For example:
576 * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
577 * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
578 * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter;
579 * for (U.first(iter); U.valid(iter); U.next(iter)) {
580 * // iter is convertible to Graph::Node
581 * cout << iter << endl;
586 ClassIt& first(ClassIt& it) const {
592 * \brief Returns whether the iterator is valid.
594 * Returns whether the iterator is valid.
596 * With the \ref first, \ref valid and \ref next methods you can
597 * iterate through the components. See the example here: \ref first.
600 bool valid(ClassIt const &it) const {
605 * \brief Steps the iterator to the next component.
607 * Steps the iterator to the next component.
609 * With the \ref first, \ref valid and \ref next methods you can
610 * iterate through the components. See the example here: \ref first.
613 ClassIt& next(ClassIt& it) const {
620 friend class UnionFindEnum;
625 ItemIt(Invalid): i(0) {}
628 operator const T& () const { return i->me; }
629 bool operator == (ItemIt it) const {
632 bool operator != (ItemIt it) const {
635 bool operator < (ItemIt it) const {
639 bool valid() const { return i != 0; }
641 void first(const ItemList &il) { l=&il; i = l->begin(); validate(); }
655 * \brief Sets the iterator to point to the first element of the component.
658 * Sets the iterator to point to the first element of the component.
660 * With the \ref first2 "first", \ref valid2 "valid"
661 * and \ref next2 "next" methods you can
662 * iterate through the elements of a component. For example
663 * (iterating through the component of the node \e node):
665 * Graph::Node node = ...;
666 * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
667 * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
668 * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter;
669 * for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) {
670 * // iiter is convertible to Graph::Node
671 * cout << iiter << endl;
676 ItemIt& first(ItemIt& it, const T& a) const {
677 it.first( * _find(m[a])->my_class );
682 * \brief Returns whether the iterator is valid.
685 * Returns whether the iterator is valid.
687 * With the \ref first2 "first", \ref valid2 "valid"
688 * and \ref next2 "next" methods you can
689 * iterate through the elements of a component.
690 * See the example here: \ref first2 "first".
693 bool valid(ItemIt const &it) const {
698 * \brief Steps the iterator to the next component.
701 * Steps the iterator to the next component.
703 * With the \ref first2 "first", \ref valid2 "valid"
704 * and \ref next2 "next" methods you can
705 * iterate through the elements of a component.
706 * See the example here: \ref first2 "first".
709 ItemIt& next(ItemIt& it) const {
721 #endif //LEMON_UNION_FIND_H