lemon/unionfind.h
changeset 2301 eb378706bd3d
parent 2006 00d59f733817
child 2308 cddae1c4fee6
equal deleted inserted replaced
7:370142914844 8:7ad965546f60
    34 namespace lemon {
    34 namespace lemon {
    35 
    35 
    36   //! \addtogroup auxdat
    36   //! \addtogroup auxdat
    37   //! @{
    37   //! @{
    38 
    38 
    39   /**
    39   /// \brief A \e Union-Find data structure implementation
    40    * \brief A \e Union-Find data structure implementation
    40   ///
    41    *
    41   /// The class implements the \e Union-Find data structure. 
    42    * The class implements the \e Union-Find data structure. 
    42   /// The union operation uses rank heuristic, while
    43    * The union operation uses rank heuristic, while
    43   /// the find operation uses path compression.
    44    * the find operation uses path compression.
    44   /// This is a very simple but efficient implementation, providing 
    45    * This is a very simple but efficient implementation, providing 
    45   /// only four methods: join (union), find, insert and size.
    46    * only four methods: join (union), find, insert and size.
    46   /// For more features see the \ref UnionFindEnum class.
    47    * For more features see the \ref UnionFindEnum class.
    47   ///
    48    *
    48   /// It is primarily used in Kruskal algorithm for finding minimal
    49    * It is primarily used in Kruskal algorithm for finding minimal
    49   /// cost spanning tree in a graph.
    50    * cost spanning tree in a graph.
    50   /// \sa kruskal()
    51    * \sa kruskal()
    51   ///
    52    *
    52   /// \pre You need to add all the elements by the \ref insert()
    53    * \pre The elements are automatically added only if the map 
    53   /// method.  
    54    * given to the constructor was filled with -1's. Otherwise you
    54   template <typename Item, typename ItemIntMap>
    55    * need to add all the elements by the \ref insert() method.
       
    56    * \bug It is not clear what the constructor parameter is used for.
       
    57    */
       
    58 
       
    59   template <typename T, typename TIntMap>
       
    60   class UnionFind {
    55   class UnionFind {
    61     
    56     
    62   public:
    57   public:
    63     typedef T ElementType;
    58     typedef Item ElementType;
    64     typedef std::pair<int,int> PairType;
       
    65 
    59 
    66   private:
    60   private:
    67     std::vector<PairType> data;
    61     // If the items vector stores negative value for an item then
    68     TIntMap& map;
    62     // that item is root item and it has -items[it] component size.
       
    63     // Else the items[it] contains the index of the parent.
       
    64     std::vector<int> items;
       
    65     ItemIntMap& index;
       
    66 
       
    67     bool rep(int idx) const {
       
    68       return items[idx] < 0;
       
    69     }
       
    70 
       
    71     int repIndex(int idx) const {
       
    72       int k = idx;
       
    73       while (!rep(k)) {
       
    74         k = items[k] ;
       
    75       }
       
    76       while (idx != k) {
       
    77         int next = items[idx];
       
    78         const_cast<int&>(items[idx]) = k;
       
    79         idx = next;
       
    80       }
       
    81       return k;
       
    82     }
    69 
    83 
    70   public:
    84   public:
    71     UnionFind(TIntMap& m) : map(m) {}
    85 
    72 
    86     /// \brief Constructor
    73     /**
    87     ///
    74      * \brief Returns the index of the element's component.
    88     /// Constructor of the UnionFind class. You should give an item to
    75      *
    89     /// integer map which will be used from the data structure. If you
    76      * The method returns the index of the element's component.
    90     /// modify directly this map that may cause segmentation fault,
    77      * This is an integer between zero and the number of inserted elements.
    91     /// invalid data structure, or infinite loop when you use again
    78      */
    92     /// the union-find.
    79 
    93     UnionFind(ItemIntMap& m) : index(m) {}
    80     int find(T a)
    94 
    81     {
    95     /// \brief Returns the index of the element's component.
    82       int comp0 = map[a];
    96     ///
    83       if (comp0 < 0) {
    97     /// The method returns the index of the element's component.
    84 	return insert(a);
    98     /// This is an integer between zero and the number of inserted elements.
    85       }
    99     ///
    86       int comp = comp0;
   100     int find(const Item& a) {
    87       int next;
   101       return repIndex(index[a]);
    88       while ( (next = data[comp].first) != comp) {
   102     }
    89 	comp = next;
   103 
    90       }
   104     /// \brief Inserts a new element into the structure.
    91       while ( (next = data[comp0].first) != comp) {
   105     ///
    92 	data[comp0].first = comp;
   106     /// This method inserts a new element into the data structure. 
    93 	comp0 = next;
   107     ///
    94       }
   108     /// The method returns the index of the new component.
    95 
   109     int insert(const Item& a) {
    96       return comp;
   110       int n = items.size();
    97     }
   111       items.push_back(-1);
    98 
   112       index.set(a,n);
    99     /**
       
   100      * \brief Inserts a new element into the structure.
       
   101      *
       
   102      * This method inserts a new element into the data structure. 
       
   103      *
       
   104      * It is not required to use this method:
       
   105      * if the map given to the constructor was filled 
       
   106      * with -1's then it is called automatically
       
   107      * on the first \ref find or \ref join.
       
   108      *
       
   109      * The method returns the index of the new component.
       
   110      */
       
   111 
       
   112     int insert(T a)
       
   113     {
       
   114       int n = data.size();
       
   115       data.push_back(std::make_pair(n, 1));
       
   116       map.set(a,n);
       
   117       return n;
   113       return n;
   118     }
   114     }
   119 
   115 
   120     /**
   116     /// \brief Joining the components of element \e a and element \e b.
   121      * \brief Joining the components of element \e a and element \e b.
   117     ///
   122      *
   118     /// This is the \e union operation of the Union-Find structure. 
   123      * This is the \e union operation of the Union-Find structure. 
   119     /// Joins the component of element \e a and component of
   124      * Joins the component of element \e a and component of
   120     /// element \e b. If \e a and \e b are in the same component then
   125      * element \e b. If \e a and \e b are in the same component then
   121     /// it returns false otherwise it returns true.
   126      * it returns false otherwise it returns true.
   122     bool join(const Item& a, const Item& b) {
   127      */
   123       int ka = repIndex(index[a]);
   128 
   124       int kb = repIndex(index[b]);
   129     bool join(T a, T b)
   125 
   130     {
   126       if ( ka == kb ) 
   131       int ca = find(a);
       
   132       int cb = find(b);
       
   133 
       
   134       if ( ca == cb ) 
       
   135 	return false;
   127 	return false;
   136 
   128 
   137       if ( data[ca].second > data[cb].second ) {
   129       if (items[ka] < items[kb]) {
   138 	data[cb].first = ca;
   130 	items[ka] += items[kb];
   139 	data[ca].second += data[cb].second;
   131 	items[kb] = ka;
   140       }
   132       } else {
   141       else {
   133 	items[kb] += items[ka];
   142 	data[ca].first = cb;
   134 	items[ka] = kb;
   143 	data[cb].second += data[ca].second;
       
   144       }
   135       }
   145       return true;
   136       return true;
   146     }
   137     }
   147 
   138 
   148     /**
   139     /// \brief Returns the size of the component of element \e a.
   149      * \brief Returns the size of the component of element \e a.
   140     ///
   150      *
   141     /// Returns the size of the component of element \e a.
   151      * Returns the size of the component of element \e a.
   142     int size(const Item& a) {
   152      */
   143       int k = repIndex(index[a]);
   153 
   144       return - items[k];
   154     int size(T a)
       
   155     {
       
   156       int ca = find(a);
       
   157       return data[ca].second;
       
   158     }
   145     }
   159 
   146 
   160   };
   147   };
   161 
   148 
   162 
   149 
   163 
   150   /// \brief A \e Union-Find data structure implementation which
   164 
   151   /// is able to enumerate the components.
   165   /*******************************************************/
   152   ///
   166 
   153   /// The class implements a \e Union-Find data structure
   167 
   154   /// which is able to enumerate the components and the items in
   168 #ifdef DEVELOPMENT_DOCS
   155   /// a component. If you don't need this feature then perhaps it's
   169 
   156   /// better to use the \ref UnionFind class which is more efficient.
   170   /**
   157   ///
   171    * \brief The auxiliary class for the \ref UnionFindEnum class.
   158   /// The union operation uses rank heuristic, while
   172    *
   159   /// the find operation uses path compression.
   173    * In the \ref UnionFindEnum class all components are represented as
   160   ///
   174    * a std::list. 
   161   /// \pre You need to add all the elements by the \ref insert()
   175    * Items of these lists are UnionFindEnumItem structures.
   162   /// method.
   176    *
   163   ///
   177    * The class has four fields:
   164   template <typename _Item, typename _ItemIntMap>
   178    *  - T me - the actual element 
   165   class UnionFindEnum {
   179    *  - IIter parent - the parent of the element in the union-find structure
   166   public:
   180    *  - int size - the size of the component of the element. 
   167     
   181    *            Only valid if the element
   168     typedef _Item Item;
   182    *            is the leader of the component.
   169     typedef _ItemIntMap ItemIntMap;
   183    *  - CIter my_class - pointer into the list of components 
   170     
   184    *            pointing to the component of the element.
   171   private:
   185    *            Only valid if the element is the leader of the component.
   172     
   186    */
   173     // If the parent stores negative value for an item then that item
   187 
   174     // is root item and it has -items[it].parent component size.  Else
   188 #endif
   175     // the items[it].parent contains the index of the parent.
   189 
   176     //
   190   template <typename T>
   177     // The \c nextItem and \c prevItem provides the double-linked
   191   struct UnionFindEnumItem {
   178     // cyclic list of one component's items. The \c prevClass and
   192 
   179     // \c nextClass gives the double linked list of the representant
   193     typedef std::list<UnionFindEnumItem> ItemList;
   180     // items. 
   194     typedef std::list<ItemList> ClassList;
   181     struct ItemT {
   195     typedef typename ItemList::iterator IIter;
   182       int parent;
   196     typedef typename ClassList::iterator CIter;
   183       Item item;
   197 
   184 
   198     T me;
   185       int nextItem, prevItem;
   199     IIter parent;
   186       int nextClass, prevClass;
   200     int size;
   187     };
   201     CIter my_class;
   188 
   202 
   189     std::vector<ItemT> items;
   203     UnionFindEnumItem() {}
   190     ItemIntMap& index;
   204     UnionFindEnumItem(const T &_me, CIter _my_class): 
   191 
   205       me(_me), size(1), my_class(_my_class) {}
   192     int firstClass;
       
   193 
       
   194 
       
   195     bool rep(int idx) const {
       
   196       return items[idx].parent < 0;
       
   197     }
       
   198 
       
   199     int repIndex(int idx) const {
       
   200       int k = idx;
       
   201       while (!rep(k)) {
       
   202         k = items[k].parent;
       
   203       }
       
   204       while (idx != k) {
       
   205         int next = items[idx].parent;
       
   206         const_cast<int&>(items[idx].parent) = k;
       
   207         idx = next;
       
   208       }
       
   209       return k;
       
   210     }
       
   211 
       
   212     void unlaceClass(int k) {
       
   213       if (items[k].prevClass != -1) {
       
   214         items[items[k].prevClass].nextClass = items[k].nextClass;
       
   215       } else {
       
   216         firstClass = items[k].nextClass;
       
   217       }
       
   218       if (items[k].nextClass != -1) {
       
   219         items[items[k].nextClass].prevClass = items[k].prevClass;
       
   220       }
       
   221     } 
       
   222 
       
   223     void spliceItems(int ak, int bk) {
       
   224       items[items[ak].prevItem].nextItem = bk;
       
   225       items[items[bk].prevItem].nextItem = ak;
       
   226       int tmp = items[ak].prevItem;
       
   227       items[ak].prevItem = items[bk].prevItem;
       
   228       items[bk].prevItem = tmp;
       
   229         
       
   230     }
       
   231 
       
   232   public:
       
   233 
       
   234     UnionFindEnum(ItemIntMap& _index) 
       
   235       : items(), index(_index), firstClass(-1) {}
       
   236     
       
   237     /// \brief Inserts the given element into a new component.
       
   238     ///
       
   239     /// This method creates a new component consisting only of the
       
   240     /// given element.
       
   241     ///
       
   242     void insert(const Item& item) {
       
   243       ItemT t;
       
   244 
       
   245       int idx = items.size();
       
   246       index.set(item, idx);
       
   247 
       
   248       t.nextItem = idx;
       
   249       t.prevItem = idx;
       
   250       t.item = item;
       
   251       t.parent = -1;
       
   252       
       
   253       t.nextClass = firstClass;
       
   254       if (firstClass != -1) {
       
   255         items[firstClass].prevClass = idx;
       
   256       }
       
   257       t.prevClass = -1;
       
   258       firstClass = idx;
       
   259 
       
   260       items.push_back(t);
       
   261     }
       
   262 
       
   263     /// \brief Inserts the given element into the component of the others.
       
   264     ///
       
   265     /// This methods inserts the element \e a into the component of the
       
   266     /// element \e comp. 
       
   267     void insert(const Item& item, const Item& comp) {
       
   268       int k = repIndex(index[comp]);
       
   269       ItemT t;
       
   270 
       
   271       int idx = items.size();
       
   272       index.set(item, idx);
       
   273 
       
   274       t.prevItem = k;
       
   275       t.nextItem = items[k].nextItem;
       
   276       items[items[k].nextItem].prevItem = idx;
       
   277       items[k].nextItem = idx;
       
   278 
       
   279       t.item = item;
       
   280       t.parent = k;
       
   281 
       
   282       --items[k].parent;
       
   283 
       
   284       items.push_back(t);
       
   285     }
       
   286 
       
   287     /// \brief Finds the leader of the component of the given element.
       
   288     ///
       
   289     /// The method returns the leader of the component of the given element.
       
   290     const Item& find(const Item &item) const {
       
   291       return items[repIndex(index[item])].item;
       
   292     }
       
   293 
       
   294     /// \brief Joining the component of element \e a and element \e b.
       
   295     ///
       
   296     /// This is the \e union operation of the Union-Find structure. 
       
   297     /// Joins the component of element \e a and component of
       
   298     /// element \e b. If \e a and \e b are in the same component then
       
   299     /// returns false else returns true.
       
   300     bool join(const Item& a, const Item& b) {
       
   301 
       
   302       int ak = repIndex(index[a]);
       
   303       int bk = repIndex(index[b]);
       
   304 
       
   305       if (ak == bk) {
       
   306 	return false;
       
   307       }
       
   308 
       
   309       if ( items[ak].parent < items[bk].parent ) {
       
   310         unlaceClass(bk);
       
   311         items[ak].parent += items[bk].parent;
       
   312 	items[bk].parent = ak;
       
   313       } else {
       
   314         unlaceClass(bk);
       
   315         items[bk].parent += items[ak].parent;
       
   316 	items[ak].parent = bk;
       
   317       }
       
   318       spliceItems(ak, bk);
       
   319 
       
   320       return true;
       
   321     }
       
   322 
       
   323     /// \brief Returns the size of the component of element \e a.
       
   324     ///
       
   325     /// Returns the size of the component of element \e a.
       
   326     int size(const Item &item) const {
       
   327       return - items[repIndex(index[item])].parent;
       
   328     }
       
   329 
       
   330     /// \brief Splits up the component of the element. 
       
   331     ///
       
   332     /// Splitting the component of the element into sigleton
       
   333     /// components (component of size one).
       
   334     void split(const Item &item) {
       
   335       int k = repIndex(index[item]);
       
   336       int idx = items[k].nextItem;
       
   337       while (idx != k) {
       
   338         int next = items[idx].nextItem;
       
   339         
       
   340         items[idx].parent = -1;
       
   341         items[idx].prevItem = idx;
       
   342         items[idx].nextItem = idx;
       
   343         
       
   344         items[idx].nextClass = firstClass;
       
   345         items[firstClass].prevClass = idx;
       
   346         firstClass = idx;
       
   347 
       
   348         idx = next;
       
   349       }
       
   350 
       
   351       items[idx].parent = -1;
       
   352       items[idx].prevItem = idx;
       
   353       items[idx].nextItem = idx;
       
   354       
       
   355       items[firstClass].prevClass = -1;
       
   356     }
       
   357 
       
   358     /// \brief Sets the given element to the leader element of its component.
       
   359     ///
       
   360     /// Sets the given element to the leader element of its component.
       
   361     void makeRep(const Item &item) {
       
   362       int nk = index[item];
       
   363       int k = repIndex(nk);
       
   364       if (nk == k) return;
       
   365       
       
   366       if (items[k].prevClass != -1) {
       
   367         items[items[k].prevClass].nextClass = nk;
       
   368       } else {
       
   369         firstClass = nk;
       
   370       }
       
   371       if (items[k].nextClass != -1) {
       
   372         items[items[k].nextClass].prevClass = nk;
       
   373       }
       
   374       
       
   375       int idx = items[k].nextItem;
       
   376       while (idx != k) {
       
   377         items[idx].parent = nk;
       
   378         idx = items[idx].nextItem;
       
   379       }
       
   380       
       
   381       items[nk].parent = items[k].parent;
       
   382       items[k].parent = nk;
       
   383     }
       
   384 
       
   385     /// \brief Removes the given element from the structure.
       
   386     ///
       
   387     /// Removes the element from its component and if the component becomes
       
   388     /// empty then removes that component from the component list.
       
   389     ///
       
   390     /// \warning It is an error to remove an element which is not in
       
   391     /// the structure.
       
   392     void erase(const Item &item) {
       
   393       int idx = index[item];
       
   394       if (rep(idx)) {
       
   395         int k = idx;
       
   396         if (items[k].parent == -1) {
       
   397           unlaceClass(idx);
       
   398           return;
       
   399         } else {
       
   400           int nk = items[k].nextItem;
       
   401           if (items[k].prevClass != -1) {
       
   402             items[items[k].prevClass].nextClass = nk;
       
   403           } else {
       
   404             firstClass = nk;
       
   405           }
       
   406           if (items[k].nextClass != -1) {
       
   407             items[items[k].nextClass].prevClass = nk;
       
   408           }
       
   409       
       
   410           int idx = items[k].nextItem;
       
   411           while (idx != k) {
       
   412             items[idx].parent = nk;
       
   413             idx = items[idx].nextItem;
       
   414           }
       
   415           
       
   416           items[nk].parent = items[k].parent + 1;
       
   417         }
       
   418       } else {
       
   419         
       
   420         int k = repIndex(idx);
       
   421         idx = items[k].nextItem;
       
   422         while (idx != k) {
       
   423           items[idx].parent = k;
       
   424           idx = items[idx].nextItem;
       
   425         }
       
   426 
       
   427         ++items[k].parent;
       
   428       }
       
   429 
       
   430       idx = index[item];      
       
   431       items[items[idx].prevItem].nextItem = items[idx].nextItem;
       
   432       items[items[idx].nextItem].prevItem = items[idx].prevItem;
       
   433 
       
   434     }    
       
   435 
       
   436     /// \brief Moves the given element to another component.
       
   437     ///
       
   438     /// This method moves the element \e a from its component
       
   439     /// to the component of \e comp.
       
   440     /// If \e a and \e comp are in the same component then
       
   441     /// it returns false otherwise it returns true.
       
   442     bool move(const Item &item, const Item &comp) {
       
   443       if (repIndex(index[item]) == repIndex(index[comp])) return false;
       
   444       erase(item);
       
   445       insert(item, comp);
       
   446       return true;
       
   447     }
       
   448 
       
   449 
       
   450     /// \brief Removes the component of the given element from the structure.
       
   451     ///
       
   452     /// Removes the component of the given element from the structure.
       
   453     ///
       
   454     /// \warning It is an error to give an element which is not in the
       
   455     /// structure.
       
   456     void eraseClass(const Item &item) {
       
   457       unlaceClass(repIndex(index[item]));
       
   458     }
       
   459 
       
   460     /// \brief Lemon style iterator for the representant items.
       
   461     ///
       
   462     /// ClassIt is a lemon style iterator for the components. It iterates
       
   463     /// on the representant items of the classes.
       
   464     class ClassIt {
       
   465     public:
       
   466       /// \brief Constructor of the iterator
       
   467       ///
       
   468       /// Constructor of the iterator
       
   469       ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
       
   470         idx = unionFind->firstClass;
       
   471       }
       
   472 
       
   473       /// \brief Constructor to get invalid iterator
       
   474       ///
       
   475       /// Constructor to get invalid iterator
       
   476       ClassIt(Invalid) : unionFind(0), idx(-1) {}
       
   477       
       
   478       /// \brief Increment operator
       
   479       ///
       
   480       /// It steps to the next representant item.
       
   481       ClassIt& operator++() {
       
   482         idx = unionFind->items[idx].nextClass;
       
   483         return *this;
       
   484       }
       
   485       
       
   486       /// \brief Conversion operator
       
   487       ///
       
   488       /// It converts the iterator to the current representant item.
       
   489       operator const Item&() const {
       
   490         return unionFind->items[idx].item;
       
   491       }
       
   492 
       
   493       /// \brief Equality operator
       
   494       ///
       
   495       /// Equality operator
       
   496       bool operator==(const ClassIt& i) { 
       
   497         return i.idx == idx;
       
   498       }
       
   499 
       
   500       /// \brief Inequality operator
       
   501       ///
       
   502       /// Inequality operator
       
   503       bool operator!=(const ClassIt& i) { 
       
   504         return i.idx != idx;
       
   505       }
       
   506       
       
   507     private:
       
   508       const UnionFindEnum* unionFind;
       
   509       int idx;
       
   510     };
       
   511 
       
   512     /// \brief Lemon style iterator for the items of a component.
       
   513     ///
       
   514     /// ClassIt is a lemon style iterator for the components. It iterates
       
   515     /// on the items of a class. By example if you want to iterate on
       
   516     /// each items of each classes then you may write the next code.
       
   517     ///\code
       
   518     /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
       
   519     ///   std::cout << "Class: ";
       
   520     ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
       
   521     ///     std::cout << toString(iit) << ' ' << std::endl;
       
   522     ///   }
       
   523     ///   std::cout << std::endl;
       
   524     /// }
       
   525     ///\endcode
       
   526     class ItemIt {
       
   527     public:
       
   528       /// \brief Constructor of the iterator
       
   529       ///
       
   530       /// Constructor of the iterator. The iterator iterates
       
   531       /// on the class of the \c item.
       
   532       ItemIt(const UnionFindEnum& ufe, const Item& item) : unionFind(&ufe) {
       
   533         idx = unionFind->repIndex(unionFind->index[item]);
       
   534       }
       
   535 
       
   536       /// \brief Constructor to get invalid iterator
       
   537       ///
       
   538       /// Constructor to get invalid iterator
       
   539       ItemIt(Invalid) : unionFind(0), idx(-1) {}
       
   540       
       
   541       /// \brief Increment operator
       
   542       ///
       
   543       /// It steps to the next item in the class.
       
   544       ItemIt& operator++() {
       
   545         idx = unionFind->items[idx].nextItem;
       
   546         if (unionFind->rep(idx)) idx = -1;
       
   547         return *this;
       
   548       }
       
   549       
       
   550       /// \brief Conversion operator
       
   551       ///
       
   552       /// It converts the iterator to the current item.
       
   553       operator const Item&() const {
       
   554         return unionFind->items[idx].item;
       
   555       }
       
   556 
       
   557       /// \brief Equality operator
       
   558       ///
       
   559       /// Equality operator
       
   560       bool operator==(const ItemIt& i) { 
       
   561         return i.idx == idx;
       
   562       }
       
   563 
       
   564       /// \brief Inequality operator
       
   565       ///
       
   566       /// Inequality operator
       
   567       bool operator!=(const ItemIt& i) { 
       
   568         return i.idx != idx;
       
   569       }
       
   570       
       
   571     private:
       
   572       const UnionFindEnum* unionFind;
       
   573       int idx;
       
   574     };
       
   575 
   206   };
   576   };
   207 
   577 
   208 
   578 
   209   /**
       
   210    * \brief A \e Union-Find data structure implementation which
       
   211    * is able to enumerate the components.
       
   212    *
       
   213    * The class implements a \e Union-Find data structure
       
   214    * which is able to enumerate the components and the items in
       
   215    * a component. If you don't need this feature then perhaps it's
       
   216    * better to use the \ref UnionFind class which is more efficient.
       
   217    *
       
   218    * The union operation uses rank heuristic, while
       
   219    * the find operation uses path compression.
       
   220    *
       
   221    * \pre You
       
   222    * need to add all the elements by the \ref insert() method.
       
   223    */
       
   224 
       
   225 
       
   226   template <typename T, template <typename Item> class Map>
       
   227   class UnionFindEnum {
       
   228 
       
   229     typedef std::list<UnionFindEnumItem<T> > ItemList;
       
   230     typedef std::list<ItemList> ClassList;
       
   231     typedef typename ItemList::iterator IIter;
       
   232     typedef typename ItemList::const_iterator IcIter;
       
   233     typedef typename ClassList::iterator CIter;
       
   234     typedef typename ClassList::const_iterator CcIter;
       
   235 
       
   236   public:
       
   237     typedef T ElementType;
       
   238     typedef UnionFindEnumItem<T> ItemType;
       
   239     typedef Map< IIter > MapType;
       
   240 
       
   241   private:
       
   242     MapType& m;
       
   243     ClassList classes;
       
   244 
       
   245     IIter _find(IIter a) const {
       
   246       IIter comp = a;
       
   247       IIter next;
       
   248       while( (next = comp->parent) != comp ) {
       
   249 	comp = next;
       
   250       }
       
   251 
       
   252       IIter comp1 = a;
       
   253       while( (next = comp1->parent) != comp ) {
       
   254 	comp1->parent = comp->parent;
       
   255 	comp1 = next;
       
   256       }
       
   257       return comp;
       
   258     }
       
   259 
       
   260     const ItemList& classOf(const T &a) const {
       
   261       return *_find(m[a])->my_class;
       
   262     }
       
   263 
       
   264   public:
       
   265     UnionFindEnum(MapType& _m) : m(_m) {}
       
   266 
       
   267 
       
   268     /**
       
   269      * \brief Inserts the given element into a new component.
       
   270      *
       
   271      * This method creates a new component consisting only of the
       
   272      * given element.
       
   273      */
       
   274 
       
   275     void insert(const T &a)
       
   276     {
       
   277 
       
   278 
       
   279       classes.push_back(ItemList());
       
   280       CIter aclass = classes.end();
       
   281       --aclass;
       
   282 
       
   283       ItemList &alist = *aclass;
       
   284       alist.push_back(ItemType(a, aclass));
       
   285       IIter ai = alist.begin();
       
   286 
       
   287       ai->parent = ai;
       
   288       m.set(a, ai);
       
   289 
       
   290     }
       
   291 
       
   292     /**
       
   293      * \brief Inserts the given element into the component of the others.
       
   294      *
       
   295      * This methods inserts the element \e a into the component of the
       
   296      * element \e comp. 
       
   297      */
       
   298 
       
   299     void insert(const T &a, const T &comp) {
       
   300       
       
   301       IIter clit = _find(m[comp]);
       
   302       ItemList &c = *clit->my_class;
       
   303       c.push_back(ItemType(a,CIter()));
       
   304       IIter ai = c.end();
       
   305       --ai;
       
   306       ai->parent = clit;
       
   307       m.set(a, ai);
       
   308       ++clit->size;
       
   309     }
       
   310 
       
   311 
       
   312     /**
       
   313      * \brief Finds the leader of the component of the given element.
       
   314      *
       
   315      * The method returns the leader of the component of the given element.
       
   316      */
       
   317 
       
   318     T find(const T &a) const {
       
   319       return _find(m[a])->me;
       
   320     }
       
   321 
       
   322 
       
   323     /**
       
   324      * \brief Joining the component of element \e a and element \e b.
       
   325      *
       
   326      * This is the \e union operation of the Union-Find structure. 
       
   327      * Joins the component of element \e a and component of
       
   328      * element \e b. If \e a and \e b are in the same component then
       
   329      * returns false else returns true.
       
   330      */
       
   331 
       
   332     bool join(T a, T b) {
       
   333 
       
   334       IIter ca = _find(m[a]);
       
   335       IIter cb = _find(m[b]);
       
   336 
       
   337       if ( ca == cb ) {
       
   338 	return false;
       
   339       }
       
   340 
       
   341       if ( ca->size > cb->size ) {
       
   342 
       
   343 	cb->parent = ca->parent;
       
   344 	ca->size += cb->size;
       
   345 	
       
   346 	ItemList &alist = *ca->my_class;
       
   347 	alist.splice(alist.end(),*cb->my_class);
       
   348 
       
   349 	classes.erase(cb->my_class);
       
   350       }
       
   351       else {
       
   352 
       
   353 	ca->parent = cb->parent;
       
   354 	cb->size += ca->size;
       
   355 	
       
   356 	ItemList &blist = *cb->my_class;
       
   357 	blist.splice(blist.end(),*ca->my_class);
       
   358 
       
   359 	classes.erase(ca->my_class);
       
   360       }
       
   361 
       
   362       return true;
       
   363     }
       
   364 
       
   365 
       
   366     /**
       
   367      * \brief Returns the size of the component of element \e a.
       
   368      *
       
   369      * Returns the size of the component of element \e a.
       
   370      */
       
   371 
       
   372     int size(const T &a) const {
       
   373       return _find(m[a])->size;
       
   374     }
       
   375 
       
   376 
       
   377     /**
       
   378      * \brief Splits up the component of the element. 
       
   379      *
       
   380      * Splitting the component of the element into sigleton
       
   381      * components (component of size one).
       
   382      */
       
   383 
       
   384     void split(const T &a) {
       
   385 
       
   386       IIter ca = _find(m[a]);
       
   387  
       
   388       if ( ca->size == 1 )
       
   389 	return;
       
   390       
       
   391       CIter aclass = ca->my_class;
       
   392 
       
   393       for(IIter curr = ca; ++curr != aclass->end(); curr=ca) {
       
   394 	classes.push_back(ItemList());
       
   395 	CIter nl = --classes.end();
       
   396 	nl->splice(nl->end(), *aclass, curr);
       
   397 
       
   398 	curr->size=1;
       
   399 	curr->parent=curr;
       
   400 	curr->my_class = nl;
       
   401       }
       
   402 
       
   403       ca->size=1;
       
   404       return;
       
   405     }
       
   406 
       
   407 
       
   408     /**
       
   409      * \brief Sets the given element to the leader element of its component.
       
   410      *
       
   411      * Sets the given element to the leader element of its component.
       
   412      */
       
   413 
       
   414     void makeRep(const T &a) {
       
   415 
       
   416       IIter ia = m[a];
       
   417       IIter la = _find(ia);
       
   418       if (la == ia) return;
       
   419 
       
   420       ia->my_class = la->my_class;
       
   421 
       
   422       ia->size = la->size;
       
   423 
       
   424       CIter l = ia->my_class;
       
   425       l->splice(l->begin(),*l,ia);
       
   426 
       
   427       ia->parent = ia;
       
   428       la->parent = ia;
       
   429     }
       
   430 
       
   431     /**
       
   432      * \brief Moves the given element to another component.
       
   433      *
       
   434      * This method moves the element \e a from its component
       
   435      * to the component of \e comp.
       
   436      * If \e a and \e comp are in the same component then
       
   437      * it returns false otherwise it returns true.
       
   438      */
       
   439 
       
   440     bool move(const T &a, const T &comp) {
       
   441 
       
   442       IIter ai = m[a];
       
   443       IIter lai = _find(ai);
       
   444       IIter clit = _find(m[comp]);
       
   445 
       
   446       if (lai == clit)
       
   447 	return false;
       
   448 
       
   449       ItemList &cl = *clit->my_class,
       
   450 	&al = *lai->my_class;
       
   451 
       
   452       bool is_leader = (lai == ai);
       
   453       bool singleton = false;
       
   454 
       
   455       if (is_leader) {
       
   456 	++lai;
       
   457       }
       
   458 
       
   459       cl.splice(cl.end(), al, ai);
       
   460 
       
   461       if (is_leader) {
       
   462 	if (ai->size == 1) {
       
   463 	  classes.erase(ai->my_class);
       
   464 	  singleton = true;
       
   465 	}
       
   466 	else {
       
   467 	  lai->size = ai->size; 
       
   468 	  lai->my_class = ai->my_class;	
       
   469 	}
       
   470       }
       
   471       if (!singleton) {
       
   472 	for (IIter i = lai; i != al.end(); ++i)
       
   473 	  i->parent = lai;
       
   474 	--lai->size;
       
   475       }
       
   476 
       
   477       ai->parent = clit;
       
   478       ++clit->size;
       
   479 
       
   480       return true;
       
   481     }
       
   482 
       
   483 
       
   484     /**
       
   485      * \brief Removes the given element from the structure.
       
   486      *
       
   487      * Removes the element from its component and if the component becomes
       
   488      * empty then removes that component from the component list.
       
   489      *
       
   490      * It is an error to remove an element which is not in the structure.
       
   491      */
       
   492     void erase(const T &a) {
       
   493 
       
   494       IIter ma = m[a];
       
   495 
       
   496       IIter la = _find(ma);
       
   497       if (la == ma) {
       
   498 	if (ma -> size == 1){
       
   499 	  classes.erase(ma->my_class);
       
   500 	  return;
       
   501 	}
       
   502 	++la;
       
   503 	la->size = ma->size; 
       
   504 	la->my_class = ma->my_class;	
       
   505       }
       
   506 
       
   507       for (IIter i = la; i != la->my_class->end(); ++i) {
       
   508 	i->parent = la;
       
   509       }
       
   510 
       
   511       la->size--;
       
   512       la->my_class->erase(ma);
       
   513     }
       
   514 
       
   515     /**
       
   516      * \brief Removes the component of the given element from the structure.
       
   517      *
       
   518      * Removes the component of the given element from the structure.
       
   519      *
       
   520      * It is an error to give an element which is not in the structure.
       
   521      */
       
   522 
       
   523     void eraseClass(const T &a) {
       
   524       IIter ma = m[a];
       
   525       classes.erase(_find(ma)->my_class);
       
   526     }
       
   527 
       
   528 
       
   529     class ClassIt {
       
   530       friend class UnionFindEnum;
       
   531 
       
   532       CcIter i;
       
   533       const ClassList *l;
       
   534 
       
   535     public:
       
   536       ClassIt(Invalid): l(0) {}
       
   537       ClassIt() {}
       
   538       ClassIt(UnionFindEnum const &ufe) {
       
   539 	l = &ufe.classes;
       
   540 	i = l->begin();
       
   541       }
       
   542       
       
   543       operator const T& () const { 
       
   544 	ItemList const &ll = *i;
       
   545 	return (ll.begin())->me;
       
   546       }
       
   547       bool operator == (ClassIt const &it) const {
       
   548 	return (l==it.l && i==it.i) || (!valid() && !it.valid());
       
   549       }
       
   550       bool operator != (ClassIt const &it) const {
       
   551 	return !(*this == it);
       
   552       }
       
   553       bool operator < (ClassIt const &it) const {
       
   554 	return (i < it.i);
       
   555       }
       
   556 
       
   557       bool operator==(Invalid) const {
       
   558 	return !valid();
       
   559       }
       
   560       bool operator!=(Invalid) const {
       
   561 	return valid();
       
   562       }
       
   563 
       
   564       ClassIt& operator++() {
       
   565 	++i;
       
   566 	return *this;
       
   567       }
       
   568 
       
   569       // obsoleted:
       
   570       bool valid() const { return l!=0 && i!=l->end(); }
       
   571     };
       
   572 
       
   573     /**
       
   574      * \brief Sets the iterator to point to the first component.
       
   575      * 
       
   576      * Sets the iterator to point to the first component.
       
   577      *
       
   578      * With the \ref first, \ref valid and \ref next methods you can
       
   579      * iterate through the components. For example:
       
   580      * \code
       
   581      * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
       
   582      * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
       
   583      * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter;
       
   584      *  for (U.first(iter); U.valid(iter); U.next(iter)) {
       
   585      *    // iter is convertible to Graph::Node
       
   586      *    cout << iter << endl;
       
   587      *  }
       
   588      * \endcode
       
   589      *
       
   590      * \bug obsoleted, use the new LEMON iterator interface instead
       
   591      */
       
   592 
       
   593     ClassIt& first(ClassIt& it) const {
       
   594       it = ClassIt(*this);
       
   595       return it;
       
   596     }
       
   597 
       
   598     /**
       
   599      * \brief Returns whether the iterator is valid.
       
   600      *
       
   601      * Returns whether the iterator is valid.
       
   602      *
       
   603      * With the \ref first, \ref valid and \ref next methods you can
       
   604      * iterate through the components. See the example here: \ref first.
       
   605      *
       
   606      * \bug obsoleted, use the new LEMON iterator interface instead
       
   607      */
       
   608 
       
   609     bool valid(ClassIt const &it) const {
       
   610       return it.valid(); 
       
   611     }
       
   612 
       
   613     /**
       
   614      * \brief Steps the iterator to the next component. 
       
   615      *
       
   616      * Steps the iterator to the next component.
       
   617      *
       
   618      * With the \ref first, \ref valid and \ref next methods you can
       
   619      * iterate through the components. See the example here: \ref first.
       
   620      */
       
   621 
       
   622     ClassIt& next(ClassIt& it) const {
       
   623       return ++it;
       
   624     }
       
   625 
       
   626 
       
   627     class ItemIt {
       
   628       friend class UnionFindEnum;
       
   629 
       
   630       IcIter i;
       
   631       const ItemList *l;
       
   632     public:
       
   633       ItemIt(Invalid): l(0) {}
       
   634       ItemIt() {}
       
   635       ItemIt(UnionFindEnum const &ufe, const T& a) {
       
   636 	l = &ufe.classOf(a);
       
   637 	i = l->begin();
       
   638       }
       
   639       
       
   640       operator const T& () const { return i->me; }
       
   641       bool operator == (ItemIt const &it) const {
       
   642 	return (l==it.l && i==it.i) || (!valid() && !it.valid());
       
   643       }
       
   644       bool operator != (ItemIt const &it) const {
       
   645 	return !(*this == it);
       
   646       }
       
   647       bool operator < (ItemIt const &it) const {
       
   648 	return (i < it.i);
       
   649       }
       
   650 
       
   651       bool operator==(Invalid) const {
       
   652 	return !valid();
       
   653       }
       
   654       bool operator!=(Invalid) const {
       
   655 	return valid();
       
   656       }
       
   657 
       
   658       ItemIt& operator++() {
       
   659 	++i;
       
   660 	return *this;
       
   661       }
       
   662 
       
   663       // obsoleted:
       
   664       bool valid() const { return l!=0 && i!=l->end(); }
       
   665     };
       
   666 
       
   667 
       
   668 
       
   669     /**
       
   670      * \brief Sets the iterator to point to the first element of the component.
       
   671      * 
       
   672      * \anchor first2 
       
   673      * Sets the iterator to point to the first element of the component.
       
   674      *
       
   675      * With the \ref first2 "first", \ref valid2 "valid" 
       
   676      * and \ref next2 "next" methods you can
       
   677      * iterate through the elements of a component. For example
       
   678      * (iterating through the component of the node \e node):
       
   679      * \code
       
   680      * Graph::Node node = ...;
       
   681      * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G);
       
   682      * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map);
       
   683      * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter;
       
   684      *   for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) {
       
   685      *     // iiter is convertible to Graph::Node
       
   686      *     cout << iiter << endl;
       
   687      *   }
       
   688      * \endcode
       
   689      *
       
   690      * \bug obsoleted, use the new LEMON iterator interface instead
       
   691      */
       
   692     
       
   693     ItemIt& first(ItemIt& it, const T& a) const {
       
   694       it = ItemIt(*this, a);
       
   695       return it;
       
   696     }
       
   697 
       
   698     /**
       
   699      * \brief Returns whether the iterator is valid.
       
   700      *
       
   701      * \anchor valid2
       
   702      * Returns whether the iterator is valid.
       
   703      *
       
   704      * With the \ref first2 "first", \ref valid2 "valid" 
       
   705      * and \ref next2 "next" methods you can
       
   706      * iterate through the elements of a component.
       
   707      * See the example here: \ref first2 "first".
       
   708      *
       
   709      * \bug obsoleted, use the new LEMON iterator interface instead
       
   710      */
       
   711 
       
   712     bool valid(ItemIt const &it) const {
       
   713       return it.valid();
       
   714     }
       
   715 
       
   716     /**
       
   717      * \brief Steps the iterator to the next component. 
       
   718      *
       
   719      * \anchor next2
       
   720      * Steps the iterator to the next component.
       
   721      *
       
   722      * With the \ref first2 "first", \ref valid2 "valid" 
       
   723      * and \ref next2 "next" methods you can
       
   724      * iterate through the elements of a component.
       
   725      * See the example here: \ref first2 "first".
       
   726      *
       
   727      * \bug obsoleted, use the new LEMON iterator interface instead
       
   728      */
       
   729 
       
   730     ItemIt& next(ItemIt& it) const {
       
   731       return ++it;
       
   732     }
       
   733     
       
   734   };
       
   735 
       
   736 
       
   737   //! @}
   579   //! @}
   738 
   580 
   739 } //namespace lemon
   581 } //namespace lemon
   740 
   582 
   741 #endif //LEMON_UNION_FIND_H
   583 #endif //LEMON_UNION_FIND_H