Minimum mean cycle algorithm contributed by Peter Kovacs.
     3  * This file is a part of LEMON, a generic C++ optimization library
 
     5  * Copyright (C) 2003-2007
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     9  * Permission to use, modify and distribute this software is granted
 
    10  * provided that this copyright notice appears in all copies. For
 
    11  * precise terms see the accompanying LICENSE file.
 
    13  * This software is provided "AS IS" with no warranty of any kind,
 
    14  * express or implied, and with no claim as to its suitability for any
 
    19 #ifndef LEMON_UNION_FIND_H
 
    20 #define LEMON_UNION_FIND_H
 
    24 //!\brief Union-Find data structures.
 
    32 #include <lemon/bits/invalid.h>
 
    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 You need to add all the elements by the \ref insert()
 
    53   template <typename _ItemIntMap>
 
    57     typedef _ItemIntMap ItemIntMap;
 
    58     typedef typename ItemIntMap::Key Item;
 
    61     // If the items vector stores negative value for an item then
 
    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;
 
    67     bool rep(int idx) const {
 
    68       return items[idx] < 0;
 
    71     int repIndex(int idx) const {
 
    77         int next = items[idx];
 
    78         const_cast<int&>(items[idx]) = k;
 
    86     /// \brief Constructor
 
    88     /// Constructor of the UnionFind class. You should give an item to
 
    89     /// integer map which will be used from the data structure. If you
 
    90     /// modify directly this map that may cause segmentation fault,
 
    91     /// invalid data structure, or infinite loop when you use again
 
    93     UnionFind(ItemIntMap& m) : index(m) {}
 
    95     /// \brief Returns the index of the element's component.
 
    97     /// The method returns the index of the element's component.
 
    98     /// This is an integer between zero and the number of inserted elements.
 
   100     int find(const Item& a) {
 
   101       return repIndex(index[a]);
 
   104     /// \brief Inserts a new element into the structure.
 
   106     /// This method inserts a new element into the data structure. 
 
   108     /// The method returns the index of the new component.
 
   109     int insert(const Item& a) {
 
   110       int n = items.size();
 
   116     /// \brief Joining the components of element \e a and element \e b.
 
   118     /// This is the \e union operation of the Union-Find structure. 
 
   119     /// 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
 
   121     /// it returns false otherwise it returns true.
 
   122     bool join(const Item& a, const Item& b) {
 
   123       int ka = repIndex(index[a]);
 
   124       int kb = repIndex(index[b]);
 
   129       if (items[ka] < items[kb]) {
 
   130 	items[ka] += items[kb];
 
   133 	items[kb] += items[ka];
 
   139     /// \brief Returns the size of the component of element \e a.
 
   141     /// Returns the size of the component of element \e a.
 
   142     int size(const Item& a) {
 
   143       int k = repIndex(index[a]);
 
   151   /// \brief A \e Union-Find data structure implementation which
 
   152   /// is able to enumerate the components.
 
   154   /// The class implements a \e Union-Find data structure
 
   155   /// which is able to enumerate the components and the items in
 
   156   /// a component. If you don't need this feature then perhaps it's
 
   157   /// better to use the \ref UnionFind class which is more efficient.
 
   159   /// The union operation uses rank heuristic, while
 
   160   /// the find operation uses path compression.
 
   162   /// \pre You need to add all the elements by the \ref insert()
 
   165   template <typename _ItemIntMap>
 
   166   class UnionFindEnum {
 
   169     typedef _ItemIntMap ItemIntMap;
 
   170     typedef typename ItemIntMap::Key Item;
 
   174     // If the parent stores negative value for an item then that item
 
   175     // is root item and it has -items[it].parent component size.  Else
 
   176     // the items[it].parent contains the index of the parent.
 
   178     // The \c nextItem and \c prevItem provides the double-linked
 
   179     // cyclic list of one component's items. The \c prevClass and
 
   180     // \c nextClass gives the double linked list of the representant
 
   186       int nextItem, prevItem;
 
   187       int nextClass, prevClass;
 
   190     std::vector<ItemT> items;
 
   196     bool rep(int idx) const {
 
   197       return items[idx].parent < 0;
 
   200     int repIndex(int idx) const {
 
   206         int next = items[idx].parent;
 
   207         const_cast<int&>(items[idx].parent) = k;
 
   213     void unlaceClass(int k) {
 
   214       if (items[k].prevClass != -1) {
 
   215         items[items[k].prevClass].nextClass = items[k].nextClass;
 
   217         firstClass = items[k].nextClass;
 
   219       if (items[k].nextClass != -1) {
 
   220         items[items[k].nextClass].prevClass = items[k].prevClass;
 
   224     void spliceItems(int ak, int bk) {
 
   225       items[items[ak].prevItem].nextItem = bk;
 
   226       items[items[bk].prevItem].nextItem = ak;
 
   227       int tmp = items[ak].prevItem;
 
   228       items[ak].prevItem = items[bk].prevItem;
 
   229       items[bk].prevItem = tmp;
 
   235     UnionFindEnum(ItemIntMap& _index) 
 
   236       : items(), index(_index), firstClass(-1) {}
 
   238     /// \brief Inserts the given element into a new component.
 
   240     /// This method creates a new component consisting only of the
 
   243     void insert(const Item& item) {
 
   246       int idx = items.size();
 
   247       index.set(item, idx);
 
   254       t.nextClass = firstClass;
 
   255       if (firstClass != -1) {
 
   256         items[firstClass].prevClass = idx;
 
   264     /// \brief Inserts the given element into the component of the others.
 
   266     /// This methods inserts the element \e a into the component of the
 
   268     void insert(const Item& item, const Item& comp) {
 
   269       int k = repIndex(index[comp]);
 
   272       int idx = items.size();
 
   273       index.set(item, idx);
 
   276       t.nextItem = items[k].nextItem;
 
   277       items[items[k].nextItem].prevItem = idx;
 
   278       items[k].nextItem = idx;
 
   288     /// \brief Finds the leader of the component of the given element.
 
   290     /// The method returns the leader of the component of the given element.
 
   291     const Item& find(const Item &item) const {
 
   292       return items[repIndex(index[item])].item;
 
   295     /// \brief Joining the component of element \e a and element \e b.
 
   297     /// This is the \e union operation of the Union-Find structure. 
 
   298     /// Joins the component of element \e a and component of
 
   299     /// element \e b. If \e a and \e b are in the same component then
 
   300     /// returns false else returns true.
 
   301     bool join(const Item& a, const Item& b) {
 
   303       int ak = repIndex(index[a]);
 
   304       int bk = repIndex(index[b]);
 
   310       if ( items[ak].parent < items[bk].parent ) {
 
   312         items[ak].parent += items[bk].parent;
 
   313 	items[bk].parent = ak;
 
   316         items[bk].parent += items[ak].parent;
 
   317 	items[ak].parent = bk;
 
   324     /// \brief Returns the size of the component of element \e a.
 
   326     /// Returns the size of the component of element \e a.
 
   327     int size(const Item &item) const {
 
   328       return - items[repIndex(index[item])].parent;
 
   331     /// \brief Splits up the component of the element. 
 
   333     /// Splitting the component of the element into sigleton
 
   334     /// components (component of size one).
 
   335     void split(const Item &item) {
 
   336       int k = repIndex(index[item]);
 
   337       int idx = items[k].nextItem;
 
   339         int next = items[idx].nextItem;
 
   341         items[idx].parent = -1;
 
   342         items[idx].prevItem = idx;
 
   343         items[idx].nextItem = idx;
 
   345         items[idx].nextClass = firstClass;
 
   346         items[firstClass].prevClass = idx;
 
   352       items[idx].parent = -1;
 
   353       items[idx].prevItem = idx;
 
   354       items[idx].nextItem = idx;
 
   356       items[firstClass].prevClass = -1;
 
   359     /// \brief Sets the given element to the leader element of its component.
 
   361     /// Sets the given element to the leader element of its component.
 
   362     void makeRep(const Item &item) {
 
   363       int nk = index[item];
 
   364       int k = repIndex(nk);
 
   367       if (items[k].prevClass != -1) {
 
   368         items[items[k].prevClass].nextClass = nk;
 
   372       if (items[k].nextClass != -1) {
 
   373         items[items[k].nextClass].prevClass = nk;
 
   376       int idx = items[k].nextItem;
 
   378         items[idx].parent = nk;
 
   379         idx = items[idx].nextItem;
 
   382       items[nk].parent = items[k].parent;
 
   383       items[k].parent = nk;
 
   386     /// \brief Removes the given element from the structure.
 
   388     /// Removes the element from its component and if the component becomes
 
   389     /// empty then removes that component from the component list.
 
   391     /// \warning It is an error to remove an element which is not in
 
   393     void erase(const Item &item) {
 
   394       int idx = index[item];
 
   397         if (items[k].parent == -1) {
 
   401           int nk = items[k].nextItem;
 
   402           if (items[k].prevClass != -1) {
 
   403             items[items[k].prevClass].nextClass = nk;
 
   407           if (items[k].nextClass != -1) {
 
   408             items[items[k].nextClass].prevClass = nk;
 
   411           int l = items[k].nextItem;
 
   413             items[l].parent = nk;
 
   414             l = items[l].nextItem;
 
   417           items[nk].parent = items[k].parent + 1;
 
   421         int k = repIndex(idx);
 
   422         idx = items[k].nextItem;
 
   424           items[idx].parent = k;
 
   425           idx = items[idx].nextItem;
 
   432       items[items[idx].prevItem].nextItem = items[idx].nextItem;
 
   433       items[items[idx].nextItem].prevItem = items[idx].prevItem;
 
   437     /// \brief Moves the given element to another component.
 
   439     /// This method moves the element \e a from its component
 
   440     /// to the component of \e comp.
 
   441     /// If \e a and \e comp are in the same component then
 
   442     /// it returns false otherwise it returns true.
 
   443     bool move(const Item &item, const Item &comp) {
 
   444       if (repIndex(index[item]) == repIndex(index[comp])) return false;
 
   451     /// \brief Removes the component of the given element from the structure.
 
   453     /// Removes the component of the given element from the structure.
 
   455     /// \warning It is an error to give an element which is not in the
 
   457     void eraseClass(const Item &item) {
 
   458       unlaceClass(repIndex(index[item]));
 
   461     /// \brief Lemon style iterator for the representant items.
 
   463     /// ClassIt is a lemon style iterator for the components. It iterates
 
   464     /// on the representant items of the classes.
 
   467       /// \brief Constructor of the iterator
 
   469       /// Constructor of the iterator
 
   470       ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
 
   471         idx = unionFind->firstClass;
 
   474       /// \brief Constructor to get invalid iterator
 
   476       /// Constructor to get invalid iterator
 
   477       ClassIt(Invalid) : unionFind(0), idx(-1) {}
 
   479       /// \brief Increment operator
 
   481       /// It steps to the next representant item.
 
   482       ClassIt& operator++() {
 
   483         idx = unionFind->items[idx].nextClass;
 
   487       /// \brief Conversion operator
 
   489       /// It converts the iterator to the current representant item.
 
   490       operator const Item&() const {
 
   491         return unionFind->items[idx].item;
 
   494       /// \brief Equality operator
 
   496       /// Equality operator
 
   497       bool operator==(const ClassIt& i) { 
 
   501       /// \brief Inequality operator
 
   503       /// Inequality operator
 
   504       bool operator!=(const ClassIt& i) { 
 
   509       const UnionFindEnum* unionFind;
 
   513     /// \brief Lemon style iterator for the items of a component.
 
   515     /// ClassIt is a lemon style iterator for the components. It iterates
 
   516     /// on the items of a class. By example if you want to iterate on
 
   517     /// each items of each classes then you may write the next code.
 
   519     /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
 
   520     ///   std::cout << "Class: ";
 
   521     ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
 
   522     ///     std::cout << toString(iit) << ' ' << std::endl;
 
   524     ///   std::cout << std::endl;
 
   529       /// \brief Constructor of the iterator
 
   531       /// Constructor of the iterator. The iterator iterates
 
   532       /// on the class of the \c item.
 
   533       ItemIt(const UnionFindEnum& ufe, const Item& item) : unionFind(&ufe) {
 
   534         idx = unionFind->repIndex(unionFind->index[item]);
 
   537       /// \brief Constructor to get invalid iterator
 
   539       /// Constructor to get invalid iterator
 
   540       ItemIt(Invalid) : unionFind(0), idx(-1) {}
 
   542       /// \brief Increment operator
 
   544       /// It steps to the next item in the class.
 
   545       ItemIt& operator++() {
 
   546         idx = unionFind->items[idx].nextItem;
 
   547         if (unionFind->rep(idx)) idx = -1;
 
   551       /// \brief Conversion operator
 
   553       /// It converts the iterator to the current item.
 
   554       operator const Item&() const {
 
   555         return unionFind->items[idx].item;
 
   558       /// \brief Equality operator
 
   560       /// Equality operator
 
   561       bool operator==(const ItemIt& i) { 
 
   565       /// \brief Inequality operator
 
   567       /// Inequality operator
 
   568       bool operator!=(const ItemIt& i) { 
 
   573       const UnionFindEnum* unionFind;
 
   584 #endif //LEMON_UNION_FIND_H