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