lemon/unionfind.h
author deba
Sun, 30 Dec 2007 18:23:32 +0000
changeset 2550 f26368148b9c
parent 2548 a3ba22ebccc6
child 2551 5004899aa870
permissions -rw-r--r--
Changing degree of tournament tree
Bug fix in union find
Small efficiency improvment in bipartite matchings
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
alpar@906
    18
alpar@921
    19
#ifndef LEMON_UNION_FIND_H
alpar@921
    20
#define LEMON_UNION_FIND_H
beckerjc@483
    21
klao@491
    22
//!\ingroup auxdat
beckerjc@483
    23
//!\file
beckerjc@483
    24
//!\brief Union-Find data structures.
alpar@774
    25
//!
beckerjc@483
    26
beckerjc@483
    27
#include <vector>
beckerjc@483
    28
#include <list>
beckerjc@483
    29
#include <utility>
beckerjc@483
    30
#include <algorithm>
beckerjc@483
    31
deba@1993
    32
#include <lemon/bits/invalid.h>
beckerjc@483
    33
alpar@921
    34
namespace lemon {
beckerjc@483
    35
deba@2308
    36
  /// \ingroup auxdat
deba@2308
    37
  ///
deba@2205
    38
  /// \brief A \e Union-Find data structure implementation
deba@2205
    39
  ///
deba@2205
    40
  /// The class implements the \e Union-Find data structure. 
deba@2205
    41
  /// The union operation uses rank heuristic, while
deba@2205
    42
  /// the find operation uses path compression.
deba@2205
    43
  /// This is a very simple but efficient implementation, providing 
deba@2205
    44
  /// only four methods: join (union), find, insert and size.
deba@2205
    45
  /// For more features see the \ref UnionFindEnum class.
deba@2205
    46
  ///
deba@2205
    47
  /// It is primarily used in Kruskal algorithm for finding minimal
deba@2205
    48
  /// cost spanning tree in a graph.
deba@2205
    49
  /// \sa kruskal()
deba@2205
    50
  ///
deba@2205
    51
  /// \pre You need to add all the elements by the \ref insert()
deba@2205
    52
  /// method.  
deba@2308
    53
  template <typename _ItemIntMap>
beckerjc@483
    54
  class UnionFind {
beckerjc@483
    55
  public:
deba@2308
    56
deba@2308
    57
    typedef _ItemIntMap ItemIntMap;
deba@2308
    58
    typedef typename ItemIntMap::Key Item;
beckerjc@483
    59
beckerjc@483
    60
  private:
deba@2205
    61
    // If the items vector stores negative value for an item then
deba@2205
    62
    // that item is root item and it has -items[it] component size.
deba@2205
    63
    // Else the items[it] contains the index of the parent.
deba@2205
    64
    std::vector<int> items;
deba@2205
    65
    ItemIntMap& index;
deba@2205
    66
deba@2205
    67
    bool rep(int idx) const {
deba@2205
    68
      return items[idx] < 0;
deba@2205
    69
    }
deba@2205
    70
deba@2205
    71
    int repIndex(int idx) const {
deba@2205
    72
      int k = idx;
deba@2205
    73
      while (!rep(k)) {
deba@2205
    74
        k = items[k] ;
deba@2205
    75
      }
deba@2205
    76
      while (idx != k) {
deba@2205
    77
        int next = items[idx];
deba@2205
    78
        const_cast<int&>(items[idx]) = k;
deba@2205
    79
        idx = next;
deba@2205
    80
      }
deba@2205
    81
      return k;
deba@2205
    82
    }
beckerjc@483
    83
beckerjc@483
    84
  public:
beckerjc@483
    85
deba@2205
    86
    /// \brief Constructor
deba@2205
    87
    ///
deba@2205
    88
    /// Constructor of the UnionFind class. You should give an item to
deba@2205
    89
    /// integer map which will be used from the data structure. If you
deba@2205
    90
    /// modify directly this map that may cause segmentation fault,
deba@2205
    91
    /// invalid data structure, or infinite loop when you use again
deba@2205
    92
    /// the union-find.
deba@2205
    93
    UnionFind(ItemIntMap& m) : index(m) {}
beckerjc@483
    94
deba@2205
    95
    /// \brief Returns the index of the element's component.
deba@2205
    96
    ///
deba@2205
    97
    /// The method returns the index of the element's component.
deba@2205
    98
    /// This is an integer between zero and the number of inserted elements.
deba@2205
    99
    ///
deba@2205
   100
    int find(const Item& a) {
deba@2205
   101
      return repIndex(index[a]);
beckerjc@483
   102
    }
beckerjc@483
   103
deba@2427
   104
    /// \brief Clears the union-find data structure
deba@2427
   105
    ///
deba@2427
   106
    /// Erase each item from the data structure.
deba@2427
   107
    void clear() {
deba@2427
   108
      items.clear();
deba@2427
   109
    }
deba@2427
   110
deba@2205
   111
    /// \brief Inserts a new element into the structure.
deba@2205
   112
    ///
deba@2205
   113
    /// This method inserts a new element into the data structure. 
deba@2205
   114
    ///
deba@2205
   115
    /// The method returns the index of the new component.
deba@2205
   116
    int insert(const Item& a) {
deba@2205
   117
      int n = items.size();
deba@2205
   118
      items.push_back(-1);
deba@2205
   119
      index.set(a,n);
beckerjc@483
   120
      return n;
beckerjc@483
   121
    }
beckerjc@483
   122
deba@2205
   123
    /// \brief Joining the components of element \e a and element \e b.
deba@2205
   124
    ///
deba@2205
   125
    /// This is the \e union operation of the Union-Find structure. 
deba@2205
   126
    /// Joins the component of element \e a and component of
deba@2205
   127
    /// element \e b. If \e a and \e b are in the same component then
deba@2205
   128
    /// it returns false otherwise it returns true.
deba@2205
   129
    bool join(const Item& a, const Item& b) {
deba@2205
   130
      int ka = repIndex(index[a]);
deba@2205
   131
      int kb = repIndex(index[b]);
beckerjc@483
   132
deba@2205
   133
      if ( ka == kb ) 
beckerjc@483
   134
	return false;
beckerjc@483
   135
deba@2205
   136
      if (items[ka] < items[kb]) {
deba@2205
   137
	items[ka] += items[kb];
deba@2205
   138
	items[kb] = ka;
deba@2205
   139
      } else {
deba@2205
   140
	items[kb] += items[ka];
deba@2205
   141
	items[ka] = kb;
beckerjc@483
   142
      }
beckerjc@483
   143
      return true;
beckerjc@483
   144
    }
beckerjc@483
   145
deba@2205
   146
    /// \brief Returns the size of the component of element \e a.
deba@2205
   147
    ///
deba@2205
   148
    /// Returns the size of the component of element \e a.
deba@2205
   149
    int size(const Item& a) {
deba@2205
   150
      int k = repIndex(index[a]);
deba@2205
   151
      return - items[k];
beckerjc@483
   152
    }
beckerjc@483
   153
beckerjc@483
   154
  };
beckerjc@483
   155
deba@2308
   156
  /// \ingroup auxdat
deba@2308
   157
  ///
deba@2205
   158
  /// \brief A \e Union-Find data structure implementation which
deba@2205
   159
  /// is able to enumerate the components.
deba@2205
   160
  ///
deba@2205
   161
  /// The class implements a \e Union-Find data structure
deba@2205
   162
  /// which is able to enumerate the components and the items in
deba@2205
   163
  /// a component. If you don't need this feature then perhaps it's
deba@2205
   164
  /// better to use the \ref UnionFind class which is more efficient.
deba@2205
   165
  ///
deba@2205
   166
  /// The union operation uses rank heuristic, while
deba@2205
   167
  /// the find operation uses path compression.
deba@2205
   168
  ///
deba@2205
   169
  /// \pre You need to add all the elements by the \ref insert()
deba@2205
   170
  /// method.
deba@2205
   171
  ///
deba@2308
   172
  template <typename _ItemIntMap>
deba@2205
   173
  class UnionFindEnum {
deba@2205
   174
  public:
deba@2205
   175
    
deba@2205
   176
    typedef _ItemIntMap ItemIntMap;
deba@2308
   177
    typedef typename ItemIntMap::Key Item;
deba@2308
   178
deba@2205
   179
  private:
deba@2205
   180
    
deba@2505
   181
    ItemIntMap& index;
deba@2505
   182
deba@2205
   183
    // If the parent stores negative value for an item then that item
deba@2505
   184
    // is root item and it has ~(items[it].parent) component id.  Else
deba@2205
   185
    // the items[it].parent contains the index of the parent.
deba@2205
   186
    //
deba@2505
   187
    // The \c next and \c prev provides the double-linked
deba@2505
   188
    // cyclic list of one component's items.
deba@2205
   189
    struct ItemT {
deba@2205
   190
      int parent;
deba@2205
   191
      Item item;
beckerjc@483
   192
deba@2505
   193
      int next, prev;
deba@2205
   194
    };
beckerjc@483
   195
deba@2205
   196
    std::vector<ItemT> items;
deba@2505
   197
    int firstFreeItem;
beckerjc@483
   198
deba@2505
   199
    struct ClassT {
deba@2505
   200
      int size;
deba@2505
   201
      int firstItem;
deba@2505
   202
      int next, prev;
deba@2505
   203
    };
deba@2505
   204
    
deba@2505
   205
    std::vector<ClassT> classes;
deba@2505
   206
    int firstClass, firstFreeClass;
deba@2505
   207
deba@2505
   208
    int newClass() {
deba@2505
   209
      if (firstFreeClass == -1) {
deba@2505
   210
	int cdx = classes.size();
deba@2505
   211
	classes.push_back(ClassT());
deba@2505
   212
	return cdx;
deba@2505
   213
      } else {
deba@2505
   214
	int cdx = firstFreeClass;
deba@2505
   215
	firstFreeClass = classes[firstFreeClass].next;
deba@2505
   216
	return cdx;
deba@2505
   217
      }
deba@2505
   218
    }
deba@2505
   219
deba@2505
   220
    int newItem() {
deba@2505
   221
      if (firstFreeItem == -1) {
deba@2505
   222
	int idx = items.size();
deba@2505
   223
	items.push_back(ItemT());
deba@2505
   224
	return idx;
deba@2505
   225
      } else {
deba@2505
   226
	int idx = firstFreeItem;
deba@2505
   227
	firstFreeItem = items[firstFreeItem].next;
deba@2505
   228
	return idx;
deba@2505
   229
      }
deba@2505
   230
    }
beckerjc@483
   231
beckerjc@483
   232
deba@2205
   233
    bool rep(int idx) const {
deba@2205
   234
      return items[idx].parent < 0;
beckerjc@483
   235
    }
beckerjc@483
   236
deba@2205
   237
    int repIndex(int idx) const {
deba@2205
   238
      int k = idx;
deba@2205
   239
      while (!rep(k)) {
deba@2205
   240
        k = items[k].parent;
deba@2205
   241
      }
deba@2205
   242
      while (idx != k) {
deba@2205
   243
        int next = items[idx].parent;
deba@2205
   244
        const_cast<int&>(items[idx].parent) = k;
deba@2205
   245
        idx = next;
deba@2205
   246
      }
deba@2205
   247
      return k;
deba@2205
   248
    }
deba@2205
   249
deba@2505
   250
    int classIndex(int idx) const {
deba@2505
   251
      return ~(items[repIndex(idx)].parent);
deba@2505
   252
    }
deba@2505
   253
deba@2505
   254
    void singletonItem(int idx) {
deba@2505
   255
      items[idx].next = idx;
deba@2505
   256
      items[idx].prev = idx;
deba@2505
   257
    }
deba@2505
   258
deba@2505
   259
    void laceItem(int idx, int rdx) {
deba@2505
   260
      items[idx].prev = rdx;
deba@2505
   261
      items[idx].next = items[rdx].next;
deba@2505
   262
      items[items[rdx].next].prev = idx;
deba@2505
   263
      items[rdx].next = idx;
deba@2505
   264
    }
deba@2505
   265
deba@2505
   266
    void unlaceItem(int idx) {
deba@2505
   267
      items[items[idx].prev].next = items[idx].next;
deba@2505
   268
      items[items[idx].next].prev = items[idx].prev;
deba@2505
   269
      
deba@2505
   270
      items[idx].next = firstFreeItem;
deba@2505
   271
      firstFreeItem = idx;
deba@2505
   272
    }
deba@2505
   273
deba@2505
   274
    void spliceItems(int ak, int bk) {
deba@2505
   275
      items[items[ak].prev].next = bk;
deba@2505
   276
      items[items[bk].prev].next = ak;
deba@2505
   277
      int tmp = items[ak].prev;
deba@2505
   278
      items[ak].prev = items[bk].prev;
deba@2505
   279
      items[bk].prev = tmp;
deba@2505
   280
        
deba@2505
   281
    }
deba@2505
   282
deba@2505
   283
    void laceClass(int cls) {
deba@2505
   284
      if (firstClass != -1) {
deba@2505
   285
        classes[firstClass].prev = cls;
deba@2205
   286
      }
deba@2505
   287
      classes[cls].next = firstClass;
deba@2505
   288
      classes[cls].prev = -1;
deba@2505
   289
      firstClass = cls;
deba@2205
   290
    } 
deba@2205
   291
deba@2505
   292
    void unlaceClass(int cls) {
deba@2505
   293
      if (classes[cls].prev != -1) {
deba@2505
   294
        classes[classes[cls].prev].next = classes[cls].next;
deba@2505
   295
      } else {
deba@2505
   296
        firstClass = classes[cls].next;
deba@2505
   297
      }
deba@2505
   298
      if (classes[cls].next != -1) {
deba@2505
   299
        classes[classes[cls].next].prev = classes[cls].prev;
deba@2505
   300
      }
deba@2505
   301
      
deba@2505
   302
      classes[cls].next = firstFreeClass;
deba@2505
   303
      firstFreeClass = cls;
deba@2505
   304
    } 
klao@2003
   305
beckerjc@483
   306
  public:
beckerjc@483
   307
deba@2205
   308
    UnionFindEnum(ItemIntMap& _index) 
deba@2505
   309
      : index(_index), items(), firstFreeItem(-1), 
deba@2505
   310
	firstClass(-1), firstFreeClass(-1) {}
deba@2205
   311
    
deba@2205
   312
    /// \brief Inserts the given element into a new component.
deba@2205
   313
    ///
deba@2205
   314
    /// This method creates a new component consisting only of the
deba@2205
   315
    /// given element.
deba@2205
   316
    ///
deba@2505
   317
    int insert(const Item& item) {
deba@2505
   318
      int idx = newItem();
beckerjc@483
   319
deba@2205
   320
      index.set(item, idx);
beckerjc@483
   321
deba@2505
   322
      singletonItem(idx);
deba@2505
   323
      items[idx].item = item;
deba@2505
   324
deba@2505
   325
      int cdx = newClass();
deba@2505
   326
deba@2505
   327
      items[idx].parent = ~cdx;
deba@2505
   328
deba@2505
   329
      laceClass(cdx);
deba@2505
   330
      classes[cdx].size = 1;
deba@2505
   331
      classes[cdx].firstItem = idx;
deba@2505
   332
deba@2505
   333
      firstClass = cdx;
deba@2205
   334
      
deba@2505
   335
      return cdx;
beckerjc@483
   336
    }
beckerjc@483
   337
deba@2205
   338
    /// \brief Inserts the given element into the component of the others.
deba@2205
   339
    ///
deba@2205
   340
    /// This methods inserts the element \e a into the component of the
deba@2205
   341
    /// element \e comp. 
deba@2505
   342
    void insert(const Item& item, int cls) {
deba@2505
   343
      int rdx = classes[cls].firstItem;
deba@2505
   344
      int idx = newItem();
beckerjc@483
   345
deba@2205
   346
      index.set(item, idx);
deba@2205
   347
deba@2505
   348
      laceItem(idx, rdx);
deba@2205
   349
deba@2505
   350
      items[idx].item = item;
deba@2505
   351
      items[idx].parent = rdx;
deba@2205
   352
deba@2505
   353
      ++classes[~(items[rdx].parent)].size;
beckerjc@483
   354
    }
beckerjc@483
   355
deba@2427
   356
    /// \brief Clears the union-find data structure
deba@2427
   357
    ///
deba@2427
   358
    /// Erase each item from the data structure.
deba@2427
   359
    void clear() {
deba@2427
   360
      items.clear();
deba@2427
   361
      firstClass = -1;
deba@2505
   362
      firstFreeItem = -1;
deba@2427
   363
    }
deba@2427
   364
deba@2505
   365
    /// \brief Finds the component of the given element.
deba@2205
   366
    ///
deba@2505
   367
    /// The method returns the component id of the given element.
deba@2505
   368
    int find(const Item &item) const {
deba@2505
   369
      return ~(items[repIndex(index[item])].parent);
beckerjc@483
   370
    }
beckerjc@483
   371
deba@2205
   372
    /// \brief Joining the component of element \e a and element \e b.
deba@2205
   373
    ///
deba@2205
   374
    /// This is the \e union operation of the Union-Find structure. 
deba@2205
   375
    /// Joins the component of element \e a and component of
deba@2205
   376
    /// element \e b. If \e a and \e b are in the same component then
deba@2505
   377
    /// returns -1 else returns the remaining class.
deba@2505
   378
    int join(const Item& a, const Item& b) {
beckerjc@483
   379
deba@2205
   380
      int ak = repIndex(index[a]);
deba@2205
   381
      int bk = repIndex(index[b]);
beckerjc@483
   382
deba@2205
   383
      if (ak == bk) {
deba@2505
   384
	return -1;
beckerjc@483
   385
      }
beckerjc@483
   386
deba@2505
   387
      int acx = ~(items[ak].parent);
deba@2505
   388
      int bcx = ~(items[bk].parent);
deba@2505
   389
deba@2505
   390
      int rcx;
deba@2505
   391
deba@2505
   392
      if (classes[acx].size > classes[bcx].size) {
deba@2505
   393
	classes[acx].size += classes[bcx].size;
deba@2205
   394
	items[bk].parent = ak;
deba@2505
   395
        unlaceClass(bcx);
deba@2505
   396
	rcx = acx;
deba@2205
   397
      } else {
deba@2505
   398
	classes[bcx].size += classes[acx].size;
deba@2205
   399
	items[ak].parent = bk;
deba@2505
   400
        unlaceClass(acx);
deba@2505
   401
	rcx = bcx;
beckerjc@483
   402
      }
deba@2205
   403
      spliceItems(ak, bk);
beckerjc@483
   404
deba@2505
   405
      return rcx;
beckerjc@483
   406
    }
beckerjc@483
   407
deba@2505
   408
    /// \brief Returns the size of the class.
deba@2205
   409
    ///
deba@2505
   410
    /// Returns the size of the class.
deba@2505
   411
    int size(int cls) const {
deba@2505
   412
      return classes[cls].size;
beckerjc@483
   413
    }
beckerjc@483
   414
deba@2505
   415
    /// \brief Splits up the component. 
deba@2205
   416
    ///
deba@2505
   417
    /// Splitting the component into singleton components (component
deba@2505
   418
    /// of size one).
deba@2505
   419
    void split(int cls) {
deba@2505
   420
      int fdx = classes[cls].firstItem;
deba@2505
   421
      int idx = items[fdx].next;
deba@2505
   422
      while (idx != fdx) {
deba@2505
   423
        int next = items[idx].next;
deba@2505
   424
deba@2505
   425
	singletonItem(idx);
deba@2505
   426
deba@2505
   427
	int cdx = newClass();        
deba@2505
   428
        items[idx].parent = ~cdx;
deba@2505
   429
deba@2505
   430
	laceClass(cdx);
deba@2505
   431
	classes[cdx].size = 1;
deba@2505
   432
	classes[cdx].firstItem = idx;
deba@2205
   433
        
deba@2205
   434
        idx = next;
beckerjc@483
   435
      }
beckerjc@483
   436
deba@2505
   437
      items[idx].prev = idx;
deba@2505
   438
      items[idx].next = idx;
deba@2505
   439
deba@2505
   440
      classes[~(items[idx].parent)].size = 1;
deba@2205
   441
      
beckerjc@483
   442
    }
beckerjc@483
   443
deba@2205
   444
    /// \brief Removes the given element from the structure.
deba@2205
   445
    ///
deba@2205
   446
    /// Removes the element from its component and if the component becomes
deba@2205
   447
    /// empty then removes that component from the component list.
deba@2205
   448
    ///
deba@2205
   449
    /// \warning It is an error to remove an element which is not in
deba@2205
   450
    /// the structure.
deba@2505
   451
    /// \warning This running time of this operation is proportional to the
deba@2505
   452
    /// number of the items in this class.
deba@2505
   453
    void erase(const Item& item) {
deba@2205
   454
      int idx = index[item];
deba@2505
   455
      int fdx = items[idx].next;
deba@2505
   456
deba@2505
   457
      int cdx = classIndex(idx);
deba@2505
   458
      if (idx == fdx) {
deba@2505
   459
	unlaceClass(cdx);
deba@2505
   460
	items[idx].next = firstFreeItem;
deba@2505
   461
	firstFreeItem = idx;
deba@2505
   462
	return;
deba@2505
   463
      } else {
deba@2505
   464
	classes[cdx].firstItem = fdx;
deba@2505
   465
	--classes[cdx].size;
deba@2505
   466
	items[fdx].parent = ~cdx;
deba@2505
   467
deba@2505
   468
	unlaceItem(idx);
deba@2505
   469
	idx = items[fdx].next;
deba@2505
   470
	while (idx != fdx) {
deba@2505
   471
	  items[idx].parent = fdx;
deba@2505
   472
	  idx = items[idx].next;
deba@2505
   473
	}
deba@2205
   474
          
beckerjc@483
   475
      }
beckerjc@483
   476
deba@2506
   477
    }
deba@2506
   478
deba@2506
   479
    /// \brief Gives back a representant item of the component.
deba@2506
   480
    ///
deba@2506
   481
    /// Gives back a representant item of the component.
deba@2506
   482
    Item item(int cls) const {
deba@2506
   483
      return items[classes[cls].firstItem].item;
deba@2506
   484
    }
beckerjc@483
   485
deba@2205
   486
    /// \brief Removes the component of the given element from the structure.
deba@2205
   487
    ///
deba@2205
   488
    /// Removes the component of the given element from the structure.
deba@2205
   489
    ///
deba@2205
   490
    /// \warning It is an error to give an element which is not in the
deba@2205
   491
    /// structure.
deba@2505
   492
    void eraseClass(int cls) {
deba@2505
   493
      int fdx = classes[cls].firstItem;
deba@2505
   494
      unlaceClass(cls);
deba@2505
   495
      items[items[fdx].prev].next = firstFreeItem;
deba@2505
   496
      firstFreeItem = fdx;
deba@2205
   497
    }
beckerjc@483
   498
deba@2205
   499
    /// \brief Lemon style iterator for the representant items.
deba@2205
   500
    ///
deba@2205
   501
    /// ClassIt is a lemon style iterator for the components. It iterates
deba@2505
   502
    /// on the ids of the classes.
deba@2205
   503
    class ClassIt {
deba@2205
   504
    public:
deba@2205
   505
      /// \brief Constructor of the iterator
deba@2205
   506
      ///
deba@2205
   507
      /// Constructor of the iterator
deba@2205
   508
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
deba@2505
   509
        cdx = unionFind->firstClass;
beckerjc@483
   510
      }
beckerjc@483
   511
deba@2205
   512
      /// \brief Constructor to get invalid iterator
deba@2205
   513
      ///
deba@2205
   514
      /// Constructor to get invalid iterator
deba@2505
   515
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
deba@2205
   516
      
deba@2205
   517
      /// \brief Increment operator
deba@2205
   518
      ///
deba@2205
   519
      /// It steps to the next representant item.
deba@2205
   520
      ClassIt& operator++() {
deba@2505
   521
        cdx = unionFind->classes[cdx].next;
deba@2205
   522
        return *this;
deba@2205
   523
      }
deba@2205
   524
      
deba@2205
   525
      /// \brief Conversion operator
deba@2205
   526
      ///
deba@2205
   527
      /// It converts the iterator to the current representant item.
deba@2505
   528
      operator int() const {
deba@2505
   529
        return cdx;
beckerjc@483
   530
      }
beckerjc@483
   531
deba@2205
   532
      /// \brief Equality operator
deba@2205
   533
      ///
deba@2205
   534
      /// Equality operator
deba@2205
   535
      bool operator==(const ClassIt& i) { 
deba@2505
   536
        return i.cdx == cdx;
deba@2205
   537
      }
beckerjc@483
   538
deba@2205
   539
      /// \brief Inequality operator
deba@2205
   540
      ///
deba@2205
   541
      /// Inequality operator
deba@2205
   542
      bool operator!=(const ClassIt& i) { 
deba@2505
   543
        return i.cdx != cdx;
klao@2003
   544
      }
beckerjc@483
   545
      
deba@2205
   546
    private:
deba@2205
   547
      const UnionFindEnum* unionFind;
deba@2505
   548
      int cdx;
deba@2205
   549
    };
deba@2205
   550
deba@2205
   551
    /// \brief Lemon style iterator for the items of a component.
deba@2205
   552
    ///
deba@2205
   553
    /// ClassIt is a lemon style iterator for the components. It iterates
deba@2205
   554
    /// on the items of a class. By example if you want to iterate on
deba@2205
   555
    /// each items of each classes then you may write the next code.
deba@2205
   556
    ///\code
deba@2205
   557
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
deba@2205
   558
    ///   std::cout << "Class: ";
deba@2205
   559
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
deba@2205
   560
    ///     std::cout << toString(iit) << ' ' << std::endl;
deba@2205
   561
    ///   }
deba@2205
   562
    ///   std::cout << std::endl;
deba@2205
   563
    /// }
deba@2205
   564
    ///\endcode
deba@2205
   565
    class ItemIt {
deba@2205
   566
    public:
deba@2205
   567
      /// \brief Constructor of the iterator
deba@2205
   568
      ///
deba@2205
   569
      /// Constructor of the iterator. The iterator iterates
deba@2205
   570
      /// on the class of the \c item.
deba@2505
   571
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
deba@2505
   572
        fdx = idx = unionFind->classes[cls].firstItem;
beckerjc@483
   573
      }
beckerjc@483
   574
deba@2205
   575
      /// \brief Constructor to get invalid iterator
deba@2205
   576
      ///
deba@2205
   577
      /// Constructor to get invalid iterator
deba@2205
   578
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
deba@2205
   579
      
deba@2205
   580
      /// \brief Increment operator
deba@2205
   581
      ///
deba@2205
   582
      /// It steps to the next item in the class.
deba@2205
   583
      ItemIt& operator++() {
deba@2505
   584
        idx = unionFind->items[idx].next;
deba@2505
   585
        if (idx == fdx) idx = -1;
deba@2205
   586
        return *this;
klao@2003
   587
      }
deba@2205
   588
      
deba@2205
   589
      /// \brief Conversion operator
deba@2205
   590
      ///
deba@2205
   591
      /// It converts the iterator to the current item.
deba@2205
   592
      operator const Item&() const {
deba@2205
   593
        return unionFind->items[idx].item;
klao@2003
   594
      }
klao@2003
   595
deba@2205
   596
      /// \brief Equality operator
deba@2205
   597
      ///
deba@2205
   598
      /// Equality operator
deba@2205
   599
      bool operator==(const ItemIt& i) { 
deba@2205
   600
        return i.idx == idx;
klao@2003
   601
      }
klao@2003
   602
deba@2205
   603
      /// \brief Inequality operator
deba@2205
   604
      ///
deba@2205
   605
      /// Inequality operator
deba@2205
   606
      bool operator!=(const ItemIt& i) { 
deba@2205
   607
        return i.idx != idx;
deba@2205
   608
      }
deba@2205
   609
      
deba@2205
   610
    private:
deba@2205
   611
      const UnionFindEnum* unionFind;
deba@2505
   612
      int idx, fdx;
beckerjc@483
   613
    };
beckerjc@483
   614
beckerjc@483
   615
  };
beckerjc@483
   616
deba@2505
   617
  /// \ingroup auxdat
deba@2505
   618
  ///
deba@2505
   619
  /// \brief A \e Extend-Find data structure implementation which
deba@2505
   620
  /// is able to enumerate the components.
deba@2505
   621
  ///
deba@2505
   622
  /// The class implements an \e Extend-Find data structure which is
deba@2505
   623
  /// able to enumerate the components and the items in a
deba@2505
   624
  /// component. The data structure is a simplification of the
deba@2505
   625
  /// Union-Find structure, and it does not allow to merge two components.
deba@2505
   626
  ///
deba@2505
   627
  /// \pre You need to add all the elements by the \ref insert()
deba@2505
   628
  /// method.
deba@2505
   629
  template <typename _ItemIntMap>
deba@2505
   630
  class ExtendFindEnum {
deba@2505
   631
  public:
deba@2505
   632
    
deba@2505
   633
    typedef _ItemIntMap ItemIntMap;
deba@2505
   634
    typedef typename ItemIntMap::Key Item;
deba@2505
   635
deba@2505
   636
  private:
deba@2505
   637
    
deba@2505
   638
    ItemIntMap& index;
deba@2505
   639
deba@2505
   640
    struct ItemT {
deba@2505
   641
      int cls;
deba@2505
   642
      Item item;
deba@2505
   643
      int next, prev;
deba@2505
   644
    };
deba@2505
   645
deba@2505
   646
    std::vector<ItemT> items;
deba@2505
   647
    int firstFreeItem;
deba@2505
   648
deba@2505
   649
    struct ClassT {
deba@2505
   650
      int firstItem;
deba@2505
   651
      int next, prev;
deba@2505
   652
    };
deba@2505
   653
deba@2505
   654
    std::vector<ClassT> classes;
deba@2505
   655
deba@2505
   656
    int firstClass, firstFreeClass;
deba@2505
   657
deba@2505
   658
    int newClass() {
deba@2505
   659
      if (firstFreeClass != -1) {
deba@2505
   660
	int cdx = firstFreeClass;
deba@2505
   661
	firstFreeClass = classes[cdx].next;
deba@2505
   662
	return cdx;
deba@2505
   663
      } else {
deba@2505
   664
	classes.push_back(ClassT());
deba@2505
   665
	return classes.size() - 1;
deba@2505
   666
      }
deba@2505
   667
    }
deba@2505
   668
deba@2505
   669
    int newItem() {
deba@2505
   670
      if (firstFreeItem != -1) {
deba@2505
   671
	int idx = firstFreeItem;
deba@2505
   672
	firstFreeItem = items[idx].next;
deba@2505
   673
	return idx;
deba@2505
   674
      } else {
deba@2505
   675
	items.push_back(ItemT());
deba@2505
   676
	return items.size() - 1;
deba@2505
   677
      }
deba@2505
   678
    }
deba@2505
   679
deba@2505
   680
  public:
deba@2505
   681
deba@2505
   682
    /// \brief Constructor
deba@2505
   683
    ExtendFindEnum(ItemIntMap& _index) 
deba@2505
   684
      : index(_index), items(), firstFreeItem(-1), 
deba@2505
   685
	classes(), firstClass(-1), firstFreeClass(-1) {}
deba@2505
   686
    
deba@2505
   687
    /// \brief Inserts the given element into a new component.
deba@2505
   688
    ///
deba@2505
   689
    /// This method creates a new component consisting only of the
deba@2505
   690
    /// given element.
deba@2505
   691
    int insert(const Item& item) {
deba@2505
   692
      int cdx = newClass();
deba@2505
   693
      classes[cdx].prev = -1;
deba@2505
   694
      classes[cdx].next = firstClass;
deba@2542
   695
      if (firstClass != -1) {
deba@2542
   696
	classes[firstClass].prev = cdx;
deba@2542
   697
      }
deba@2505
   698
      firstClass = cdx;
deba@2505
   699
      
deba@2505
   700
      int idx = newItem();
deba@2505
   701
      items[idx].item = item;
deba@2505
   702
      items[idx].cls = cdx;
deba@2505
   703
      items[idx].prev = idx;
deba@2505
   704
      items[idx].next = idx;
deba@2505
   705
deba@2505
   706
      classes[cdx].firstItem = idx;
deba@2505
   707
deba@2505
   708
      index.set(item, idx);
deba@2505
   709
      
deba@2505
   710
      return cdx;
deba@2505
   711
    }
deba@2505
   712
deba@2505
   713
    /// \brief Inserts the given element into the given component.
deba@2505
   714
    ///
deba@2505
   715
    /// This methods inserts the element \e item a into the \e cls class.
deba@2505
   716
    void insert(const Item& item, int cls) {
deba@2505
   717
      int idx = newItem();
deba@2505
   718
      int rdx = classes[cls].firstItem;
deba@2505
   719
      items[idx].item = item;
deba@2505
   720
      items[idx].cls = cls;
deba@2505
   721
deba@2505
   722
      items[idx].prev = rdx;
deba@2505
   723
      items[idx].next = items[rdx].next;
deba@2505
   724
      items[items[rdx].next].prev = idx;
deba@2505
   725
      items[rdx].next = idx;
deba@2505
   726
deba@2505
   727
      index.set(item, idx);
deba@2505
   728
    }
deba@2505
   729
deba@2505
   730
    /// \brief Clears the union-find data structure
deba@2505
   731
    ///
deba@2505
   732
    /// Erase each item from the data structure.
deba@2505
   733
    void clear() {
deba@2505
   734
      items.clear();
deba@2505
   735
      classes.clear;
deba@2505
   736
      firstClass = firstFreeClass = firstFreeItem = -1;
deba@2505
   737
    }
deba@2505
   738
deba@2505
   739
    /// \brief Gives back the class of the \e item.
deba@2505
   740
    ///
deba@2505
   741
    /// Gives back the class of the \e item.
deba@2505
   742
    int find(const Item &item) const {
deba@2505
   743
      return items[index[item]].cls;
deba@2505
   744
    }
deba@2506
   745
deba@2506
   746
    /// \brief Gives back a representant item of the component.
deba@2506
   747
    ///
deba@2506
   748
    /// Gives back a representant item of the component.
deba@2506
   749
    Item item(int cls) const {
deba@2506
   750
      return items[classes[cls].firstItem].item;
deba@2506
   751
    }
deba@2505
   752
    
deba@2505
   753
    /// \brief Removes the given element from the structure.
deba@2505
   754
    ///
deba@2505
   755
    /// Removes the element from its component and if the component becomes
deba@2505
   756
    /// empty then removes that component from the component list.
deba@2505
   757
    ///
deba@2505
   758
    /// \warning It is an error to remove an element which is not in
deba@2505
   759
    /// the structure.
deba@2505
   760
    void erase(const Item &item) {
deba@2505
   761
      int idx = index[item];
deba@2505
   762
      int cdx = items[idx].cls;
deba@2505
   763
      
deba@2505
   764
      if (idx == items[idx].next) {
deba@2505
   765
	if (classes[cdx].prev != -1) {
deba@2505
   766
	  classes[classes[cdx].prev].next = classes[cdx].next; 
deba@2505
   767
	} else {
deba@2505
   768
	  firstClass = classes[cdx].next;
deba@2505
   769
	}
deba@2505
   770
	if (classes[cdx].next != -1) {
deba@2505
   771
	  classes[classes[cdx].next].prev = classes[cdx].prev; 
deba@2505
   772
	}
deba@2505
   773
	classes[cdx].next = firstFreeClass;
deba@2505
   774
	firstFreeClass = cdx;
deba@2505
   775
      } else {
deba@2505
   776
	classes[cdx].firstItem = items[idx].next;
deba@2505
   777
	items[items[idx].next].prev = items[idx].prev;
deba@2505
   778
	items[items[idx].prev].next = items[idx].next;
deba@2505
   779
      }
deba@2505
   780
      items[idx].next = firstFreeItem;
deba@2505
   781
      firstFreeItem = idx;
deba@2505
   782
	
deba@2505
   783
    }    
deba@2505
   784
deba@2505
   785
    
deba@2505
   786
    /// \brief Removes the component of the given element from the structure.
deba@2505
   787
    ///
deba@2505
   788
    /// Removes the component of the given element from the structure.
deba@2505
   789
    ///
deba@2505
   790
    /// \warning It is an error to give an element which is not in the
deba@2505
   791
    /// structure.
deba@2505
   792
    void eraseClass(int cdx) {
deba@2505
   793
      int idx = classes[cdx].firstItem;
deba@2505
   794
      items[items[idx].prev].next = firstFreeItem;
deba@2505
   795
      firstFreeItem = idx;
deba@2505
   796
deba@2505
   797
      if (classes[cdx].prev != -1) {
deba@2505
   798
	classes[classes[cdx].prev].next = classes[cdx].next; 
deba@2505
   799
      } else {
deba@2505
   800
	firstClass = classes[cdx].next;
deba@2505
   801
      }
deba@2505
   802
      if (classes[cdx].next != -1) {
deba@2505
   803
	classes[classes[cdx].next].prev = classes[cdx].prev; 
deba@2505
   804
      }
deba@2505
   805
      classes[cdx].next = firstFreeClass;
deba@2505
   806
      firstFreeClass = cdx;
deba@2505
   807
    }
deba@2505
   808
deba@2505
   809
    /// \brief Lemon style iterator for the classes.
deba@2505
   810
    ///
deba@2505
   811
    /// ClassIt is a lemon style iterator for the components. It iterates
deba@2505
   812
    /// on the ids of classes.
deba@2505
   813
    class ClassIt {
deba@2505
   814
    public:
deba@2505
   815
      /// \brief Constructor of the iterator
deba@2505
   816
      ///
deba@2505
   817
      /// Constructor of the iterator
deba@2505
   818
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
deba@2505
   819
        cdx = extendFind->firstClass;
deba@2505
   820
      }
deba@2505
   821
deba@2505
   822
      /// \brief Constructor to get invalid iterator
deba@2505
   823
      ///
deba@2505
   824
      /// Constructor to get invalid iterator
deba@2505
   825
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
deba@2505
   826
      
deba@2505
   827
      /// \brief Increment operator
deba@2505
   828
      ///
deba@2505
   829
      /// It steps to the next representant item.
deba@2505
   830
      ClassIt& operator++() {
deba@2505
   831
        cdx = extendFind->classes[cdx].next;
deba@2505
   832
        return *this;
deba@2505
   833
      }
deba@2505
   834
      
deba@2505
   835
      /// \brief Conversion operator
deba@2505
   836
      ///
deba@2505
   837
      /// It converts the iterator to the current class id.
deba@2505
   838
      operator int() const {
deba@2505
   839
        return cdx;
deba@2505
   840
      }
deba@2505
   841
deba@2505
   842
      /// \brief Equality operator
deba@2505
   843
      ///
deba@2505
   844
      /// Equality operator
deba@2505
   845
      bool operator==(const ClassIt& i) { 
deba@2505
   846
        return i.cdx == cdx;
deba@2505
   847
      }
deba@2505
   848
deba@2505
   849
      /// \brief Inequality operator
deba@2505
   850
      ///
deba@2505
   851
      /// Inequality operator
deba@2505
   852
      bool operator!=(const ClassIt& i) { 
deba@2505
   853
        return i.cdx != cdx;
deba@2505
   854
      }
deba@2505
   855
      
deba@2505
   856
    private:
deba@2505
   857
      const ExtendFindEnum* extendFind;
deba@2505
   858
      int cdx;
deba@2505
   859
    };
deba@2505
   860
deba@2505
   861
    /// \brief Lemon style iterator for the items of a component.
deba@2505
   862
    ///
deba@2505
   863
    /// ClassIt is a lemon style iterator for the components. It iterates
deba@2505
   864
    /// on the items of a class. By example if you want to iterate on
deba@2505
   865
    /// each items of each classes then you may write the next code.
deba@2505
   866
    ///\code
deba@2505
   867
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
deba@2505
   868
    ///   std::cout << "Class: ";
deba@2505
   869
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
deba@2505
   870
    ///     std::cout << toString(iit) << ' ' << std::endl;
deba@2505
   871
    ///   }
deba@2505
   872
    ///   std::cout << std::endl;
deba@2505
   873
    /// }
deba@2505
   874
    ///\endcode
deba@2505
   875
    class ItemIt {
deba@2505
   876
    public:
deba@2505
   877
      /// \brief Constructor of the iterator
deba@2505
   878
      ///
deba@2505
   879
      /// Constructor of the iterator. The iterator iterates
deba@2505
   880
      /// on the class of the \c item.
deba@2505
   881
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
deba@2505
   882
        fdx = idx = extendFind->classes[cls].firstItem;
deba@2505
   883
      }
deba@2505
   884
deba@2505
   885
      /// \brief Constructor to get invalid iterator
deba@2505
   886
      ///
deba@2505
   887
      /// Constructor to get invalid iterator
deba@2505
   888
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
deba@2505
   889
      
deba@2505
   890
      /// \brief Increment operator
deba@2505
   891
      ///
deba@2505
   892
      /// It steps to the next item in the class.
deba@2505
   893
      ItemIt& operator++() {
deba@2505
   894
        idx = extendFind->items[idx].next;
deba@2505
   895
	if (fdx == idx) idx = -1;
deba@2505
   896
        return *this;
deba@2505
   897
      }
deba@2505
   898
      
deba@2505
   899
      /// \brief Conversion operator
deba@2505
   900
      ///
deba@2505
   901
      /// It converts the iterator to the current item.
deba@2505
   902
      operator const Item&() const {
deba@2505
   903
        return extendFind->items[idx].item;
deba@2505
   904
      }
deba@2505
   905
deba@2505
   906
      /// \brief Equality operator
deba@2505
   907
      ///
deba@2505
   908
      /// Equality operator
deba@2505
   909
      bool operator==(const ItemIt& i) { 
deba@2505
   910
        return i.idx == idx;
deba@2505
   911
      }
deba@2505
   912
deba@2505
   913
      /// \brief Inequality operator
deba@2505
   914
      ///
deba@2505
   915
      /// Inequality operator
deba@2505
   916
      bool operator!=(const ItemIt& i) { 
deba@2505
   917
        return i.idx != idx;
deba@2505
   918
      }
deba@2505
   919
      
deba@2505
   920
    private:
deba@2505
   921
      const ExtendFindEnum* extendFind;
deba@2505
   922
      int idx, fdx;
deba@2505
   923
    };
deba@2505
   924
deba@2505
   925
  };
beckerjc@483
   926
deba@2548
   927
  /// \ingroup auxdat
deba@2548
   928
  ///
deba@2548
   929
  /// \brief A \e Union-Find data structure implementation which
deba@2548
   930
  /// is able to store a priority for each item and retrieve the minimum of
deba@2548
   931
  /// each class.
deba@2548
   932
  ///
deba@2548
   933
  /// A \e Union-Find data structure implementation which is able to
deba@2548
   934
  /// store a priority for each item and retrieve the minimum of each
deba@2548
   935
  /// class. In addition, it supports the joining and splitting the
deba@2548
   936
  /// components. If you don't need this feature then you makes
deba@2548
   937
  /// better to use the \ref UnionFind class which is more efficient.
deba@2548
   938
  ///
deba@2548
   939
  /// The union-find data strcuture based on a (2, 16)-tree with a
deba@2548
   940
  /// tournament minimum selection on the internal nodes. The insert
deba@2548
   941
  /// operation takes O(1), the find, set, decrease and increase takes
deba@2548
   942
  /// O(log(n)), where n is the number of nodes in the current
deba@2548
   943
  /// component.  The complexity of join and split is O(log(n)*k),
deba@2548
   944
  /// where n is the sum of the number of the nodes and k is the
deba@2548
   945
  /// number of joined components or the number of the components
deba@2548
   946
  /// after the split.
deba@2548
   947
  ///
deba@2548
   948
  /// \pre You need to add all the elements by the \ref insert()
deba@2548
   949
  /// method.
deba@2548
   950
  ///
deba@2548
   951
  template <typename _Value, typename _ItemIntMap, 
deba@2548
   952
            typename _Comp = std::less<_Value> >
deba@2548
   953
  class HeapUnionFind {
deba@2548
   954
  public:
deba@2548
   955
    
deba@2548
   956
    typedef _Value Value;
deba@2548
   957
    typedef typename _ItemIntMap::Key Item;
deba@2548
   958
deba@2548
   959
    typedef _ItemIntMap ItemIntMap;
deba@2548
   960
deba@2548
   961
    typedef _Comp Comp;
deba@2548
   962
deba@2548
   963
  private:
deba@2548
   964
deba@2550
   965
    static const int cmax = 16;
deba@2548
   966
deba@2548
   967
    ItemIntMap& index;
deba@2548
   968
deba@2548
   969
    struct ClassNode {
deba@2548
   970
      int parent;
deba@2548
   971
      int depth;
deba@2548
   972
deba@2548
   973
      int left, right;
deba@2548
   974
      int next, prev;
deba@2548
   975
    };
deba@2548
   976
deba@2548
   977
    int first_class;
deba@2548
   978
    int first_free_class;
deba@2548
   979
    std::vector<ClassNode> classes;
deba@2548
   980
deba@2548
   981
    int newClass() {
deba@2548
   982
      if (first_free_class < 0) {
deba@2548
   983
        int id = classes.size();
deba@2548
   984
        classes.push_back(ClassNode());
deba@2548
   985
        return id;
deba@2548
   986
      } else {
deba@2548
   987
        int id = first_free_class;
deba@2548
   988
        first_free_class = classes[id].next;
deba@2548
   989
        return id;
deba@2548
   990
      }
deba@2548
   991
    }
deba@2548
   992
deba@2548
   993
    void deleteClass(int id) {
deba@2548
   994
      classes[id].next = first_free_class;
deba@2548
   995
      first_free_class = id;
deba@2548
   996
    }
deba@2548
   997
deba@2548
   998
    struct ItemNode {
deba@2548
   999
      int parent;
deba@2548
  1000
      Item item;
deba@2548
  1001
      Value prio;
deba@2548
  1002
      int next, prev;
deba@2548
  1003
      int left, right;
deba@2548
  1004
      int size;
deba@2548
  1005
    };
deba@2548
  1006
deba@2548
  1007
    int first_free_node;
deba@2548
  1008
    std::vector<ItemNode> nodes;
deba@2548
  1009
deba@2548
  1010
    int newNode() {
deba@2548
  1011
      if (first_free_node < 0) {
deba@2548
  1012
        int id = nodes.size();
deba@2548
  1013
        nodes.push_back(ItemNode());
deba@2548
  1014
        return id;
deba@2548
  1015
      } else {
deba@2548
  1016
        int id = first_free_node;
deba@2548
  1017
        first_free_node = nodes[id].next;
deba@2548
  1018
        return id;
deba@2548
  1019
      }
deba@2548
  1020
    }
deba@2548
  1021
deba@2548
  1022
    void deleteNode(int id) {
deba@2548
  1023
      nodes[id].next = first_free_node;
deba@2548
  1024
      first_free_node = id;
deba@2548
  1025
    }
deba@2548
  1026
deba@2548
  1027
    Comp comp;
deba@2548
  1028
deba@2548
  1029
    int findClass(int id) const {
deba@2548
  1030
      int kd = id;
deba@2548
  1031
      while (kd >= 0) {
deba@2548
  1032
        kd = nodes[kd].parent;
deba@2548
  1033
      }
deba@2548
  1034
      return ~kd;
deba@2548
  1035
    }
deba@2548
  1036
deba@2548
  1037
    int leftNode(int id) const {
deba@2548
  1038
      int kd = ~(classes[id].parent);
deba@2548
  1039
      for (int i = 0; i < classes[id].depth; ++i) {
deba@2548
  1040
        kd = nodes[kd].left;
deba@2548
  1041
      }
deba@2548
  1042
      return kd;
deba@2548
  1043
    }
deba@2548
  1044
deba@2548
  1045
    int nextNode(int id) const {
deba@2548
  1046
      int depth = 0;
deba@2548
  1047
      while (id >= 0 && nodes[id].next == -1) {
deba@2548
  1048
        id = nodes[id].parent;
deba@2548
  1049
        ++depth;
deba@2548
  1050
      }
deba@2548
  1051
      if (id < 0) {
deba@2548
  1052
        return -1;
deba@2548
  1053
      }
deba@2548
  1054
      id = nodes[id].next;
deba@2548
  1055
      while (depth--) {
deba@2548
  1056
        id = nodes[id].left;      
deba@2548
  1057
      }
deba@2548
  1058
      return id;
deba@2548
  1059
    }
deba@2548
  1060
deba@2548
  1061
deba@2548
  1062
    void setPrio(int id) {
deba@2548
  1063
      int jd = nodes[id].left;
deba@2548
  1064
      nodes[id].prio = nodes[jd].prio;
deba@2548
  1065
      nodes[id].item = nodes[jd].item;
deba@2548
  1066
      jd = nodes[jd].next;
deba@2548
  1067
      while (jd != -1) {
deba@2548
  1068
        if (comp(nodes[jd].prio, nodes[id].prio)) {
deba@2548
  1069
          nodes[id].prio = nodes[jd].prio;
deba@2548
  1070
          nodes[id].item = nodes[jd].item;
deba@2548
  1071
        }
deba@2548
  1072
        jd = nodes[jd].next;
deba@2548
  1073
      }
deba@2548
  1074
    }
deba@2548
  1075
deba@2548
  1076
    void push(int id, int jd) {
deba@2548
  1077
      nodes[id].size = 1;
deba@2548
  1078
      nodes[id].left = nodes[id].right = jd;
deba@2548
  1079
      nodes[jd].next = nodes[jd].prev = -1;
deba@2548
  1080
      nodes[jd].parent = id;
deba@2548
  1081
    }
deba@2548
  1082
deba@2548
  1083
    void pushAfter(int id, int jd) {
deba@2548
  1084
      int kd = nodes[id].parent;
deba@2548
  1085
      if (nodes[id].next != -1) {
deba@2548
  1086
        nodes[nodes[id].next].prev = jd;
deba@2548
  1087
        if (kd >= 0) {
deba@2548
  1088
          nodes[kd].size += 1;
deba@2548
  1089
        }
deba@2548
  1090
      } else {
deba@2548
  1091
        if (kd >= 0) {
deba@2548
  1092
          nodes[kd].right = jd;
deba@2548
  1093
          nodes[kd].size += 1;
deba@2548
  1094
        }
deba@2548
  1095
      }
deba@2548
  1096
      nodes[jd].next = nodes[id].next;
deba@2548
  1097
      nodes[jd].prev = id;
deba@2548
  1098
      nodes[id].next = jd;
deba@2548
  1099
      nodes[jd].parent = kd;
deba@2548
  1100
    }
deba@2548
  1101
deba@2548
  1102
    void pushRight(int id, int jd) {
deba@2548
  1103
      nodes[id].size += 1;
deba@2548
  1104
      nodes[jd].prev = nodes[id].right;
deba@2548
  1105
      nodes[jd].next = -1;
deba@2548
  1106
      nodes[nodes[id].right].next = jd;
deba@2548
  1107
      nodes[id].right = jd;
deba@2548
  1108
      nodes[jd].parent = id;
deba@2548
  1109
    }
deba@2548
  1110
deba@2548
  1111
    void popRight(int id) {
deba@2548
  1112
      nodes[id].size -= 1;
deba@2548
  1113
      int jd = nodes[id].right;
deba@2548
  1114
      nodes[nodes[jd].prev].next = -1;
deba@2548
  1115
      nodes[id].right = nodes[jd].prev;
deba@2548
  1116
    }
deba@2548
  1117
deba@2548
  1118
    void splice(int id, int jd) {
deba@2548
  1119
      nodes[id].size += nodes[jd].size;
deba@2548
  1120
      nodes[nodes[id].right].next = nodes[jd].left;
deba@2548
  1121
      nodes[nodes[jd].left].prev = nodes[id].right;
deba@2548
  1122
      int kd = nodes[jd].left;
deba@2548
  1123
      while (kd != -1) {
deba@2548
  1124
        nodes[kd].parent = id;
deba@2548
  1125
        kd = nodes[kd].next;
deba@2548
  1126
      }
deba@2550
  1127
      nodes[id].right = nodes[jd].right;
deba@2548
  1128
    }
deba@2548
  1129
deba@2548
  1130
    void split(int id, int jd) {
deba@2548
  1131
      int kd = nodes[id].parent;
deba@2548
  1132
      nodes[kd].right = nodes[id].prev;
deba@2548
  1133
      nodes[nodes[id].prev].next = -1;
deba@2548
  1134
      
deba@2548
  1135
      nodes[jd].left = id;
deba@2548
  1136
      nodes[id].prev = -1;
deba@2548
  1137
      int num = 0;
deba@2548
  1138
      while (id != -1) {
deba@2548
  1139
        nodes[id].parent = jd;
deba@2548
  1140
        nodes[jd].right = id;
deba@2548
  1141
        id = nodes[id].next;
deba@2548
  1142
        ++num;
deba@2548
  1143
      }      
deba@2548
  1144
      nodes[kd].size -= num;
deba@2548
  1145
      nodes[jd].size = num;
deba@2548
  1146
    }
deba@2548
  1147
deba@2548
  1148
    void pushLeft(int id, int jd) {
deba@2548
  1149
      nodes[id].size += 1;
deba@2548
  1150
      nodes[jd].next = nodes[id].left;
deba@2548
  1151
      nodes[jd].prev = -1;
deba@2548
  1152
      nodes[nodes[id].left].prev = jd;
deba@2548
  1153
      nodes[id].left = jd;
deba@2548
  1154
      nodes[jd].parent = id;
deba@2548
  1155
    }
deba@2548
  1156
deba@2548
  1157
    void popLeft(int id) {
deba@2548
  1158
      nodes[id].size -= 1;
deba@2548
  1159
      int jd = nodes[id].left;
deba@2548
  1160
      nodes[nodes[jd].next].prev = -1;
deba@2548
  1161
      nodes[id].left = nodes[jd].next;
deba@2548
  1162
    }
deba@2548
  1163
deba@2548
  1164
    void repairLeft(int id) {
deba@2548
  1165
      int jd = ~(classes[id].parent);
deba@2548
  1166
      while (nodes[jd].left != -1) {
deba@2548
  1167
	int kd = nodes[jd].left;
deba@2548
  1168
	if (nodes[jd].size == 1) {
deba@2548
  1169
	  if (nodes[jd].parent < 0) {
deba@2548
  1170
	    classes[id].parent = ~kd;
deba@2548
  1171
	    classes[id].depth -= 1;
deba@2548
  1172
	    nodes[kd].parent = ~id;
deba@2548
  1173
	    deleteNode(jd);
deba@2548
  1174
	    jd = kd;
deba@2548
  1175
	  } else {
deba@2548
  1176
	    int pd = nodes[jd].parent;
deba@2548
  1177
	    if (nodes[nodes[jd].next].size < cmax) {
deba@2548
  1178
	      pushLeft(nodes[jd].next, nodes[jd].left);
deba@2548
  1179
	      if (less(nodes[jd].left, nodes[jd].next)) {
deba@2548
  1180
		nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio;
deba@2548
  1181
		nodes[nodes[jd].next].item = nodes[nodes[jd].left].item;
deba@2548
  1182
	      } 
deba@2548
  1183
	      popLeft(pd);
deba@2548
  1184
	      deleteNode(jd);
deba@2548
  1185
	      jd = pd;
deba@2548
  1186
	    } else {
deba@2548
  1187
	      int ld = nodes[nodes[jd].next].left;
deba@2548
  1188
	      popLeft(nodes[jd].next);
deba@2548
  1189
	      pushRight(jd, ld);
deba@2548
  1190
	      if (less(ld, nodes[jd].left)) {
deba@2548
  1191
		nodes[jd].item = nodes[ld].item;
deba@2548
  1192
		nodes[jd].prio = nodes[jd].prio;
deba@2548
  1193
	      }
deba@2548
  1194
	      if (nodes[nodes[jd].next].item == nodes[ld].item) {
deba@2548
  1195
		setPrio(nodes[jd].next);
deba@2548
  1196
	      }
deba@2548
  1197
	      jd = nodes[jd].left;
deba@2548
  1198
	    }
deba@2548
  1199
	  }
deba@2548
  1200
	} else {
deba@2548
  1201
	  jd = nodes[jd].left;
deba@2548
  1202
	}
deba@2548
  1203
      }
deba@2548
  1204
    }    
deba@2548
  1205
deba@2548
  1206
    void repairRight(int id) {
deba@2548
  1207
      int jd = ~(classes[id].parent);
deba@2548
  1208
      while (nodes[jd].right != -1) {
deba@2548
  1209
	int kd = nodes[jd].right;
deba@2548
  1210
	if (nodes[jd].size == 1) {
deba@2548
  1211
	  if (nodes[jd].parent < 0) {
deba@2548
  1212
	    classes[id].parent = ~kd;
deba@2548
  1213
	    classes[id].depth -= 1;
deba@2548
  1214
	    nodes[kd].parent = ~id;
deba@2548
  1215
	    deleteNode(jd);
deba@2548
  1216
	    jd = kd;
deba@2548
  1217
	  } else {
deba@2548
  1218
	    int pd = nodes[jd].parent;
deba@2548
  1219
	    if (nodes[nodes[jd].prev].size < cmax) {
deba@2548
  1220
	      pushRight(nodes[jd].prev, nodes[jd].right);
deba@2548
  1221
	      if (less(nodes[jd].right, nodes[jd].prev)) {
deba@2548
  1222
		nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio;
deba@2548
  1223
		nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item;
deba@2548
  1224
	      } 
deba@2548
  1225
	      popRight(pd);
deba@2548
  1226
	      deleteNode(jd);
deba@2548
  1227
	      jd = pd;
deba@2548
  1228
	    } else {
deba@2548
  1229
	      int ld = nodes[nodes[jd].prev].right;
deba@2548
  1230
	      popRight(nodes[jd].prev);
deba@2548
  1231
	      pushLeft(jd, ld);
deba@2548
  1232
	      if (less(ld, nodes[jd].right)) {
deba@2548
  1233
		nodes[jd].item = nodes[ld].item;
deba@2548
  1234
		nodes[jd].prio = nodes[jd].prio;
deba@2548
  1235
	      }
deba@2548
  1236
	      if (nodes[nodes[jd].prev].item == nodes[ld].item) {
deba@2548
  1237
		setPrio(nodes[jd].prev);
deba@2548
  1238
	      }
deba@2548
  1239
	      jd = nodes[jd].right;
deba@2548
  1240
	    }
deba@2548
  1241
	  }
deba@2548
  1242
	} else {
deba@2548
  1243
	  jd = nodes[jd].right;
deba@2548
  1244
	}
deba@2548
  1245
      }
deba@2548
  1246
    }
deba@2548
  1247
deba@2548
  1248
deba@2548
  1249
    bool less(int id, int jd) const {
deba@2548
  1250
      return comp(nodes[id].prio, nodes[jd].prio);
deba@2548
  1251
    }
deba@2548
  1252
deba@2548
  1253
    bool equal(int id, int jd) const {
deba@2548
  1254
      return !less(id, jd) && !less(jd, id);
deba@2548
  1255
    }
deba@2548
  1256
deba@2548
  1257
deba@2548
  1258
  public:
deba@2548
  1259
deba@2548
  1260
    /// \brief Returns true when the given class is alive.
deba@2548
  1261
    ///
deba@2548
  1262
    /// Returns true when the given class is alive, ie. the class is
deba@2548
  1263
    /// not nested into other class.
deba@2548
  1264
    bool alive(int cls) const {
deba@2548
  1265
      return classes[cls].parent < 0;
deba@2548
  1266
    }
deba@2548
  1267
deba@2548
  1268
    /// \brief Returns true when the given class is trivial.
deba@2548
  1269
    ///
deba@2548
  1270
    /// Returns true when the given class is trivial, ie. the class
deba@2548
  1271
    /// contains just one item directly.
deba@2548
  1272
    bool trivial(int cls) const {
deba@2548
  1273
      return classes[cls].left == -1;
deba@2548
  1274
    }
deba@2548
  1275
deba@2548
  1276
    /// \brief Constructs the union-find.
deba@2548
  1277
    ///
deba@2548
  1278
    /// Constructs the union-find.  
deba@2548
  1279
    /// \brief _index The index map of the union-find. The data
deba@2548
  1280
    /// structure uses internally for store references.
deba@2548
  1281
    HeapUnionFind(ItemIntMap& _index) 
deba@2548
  1282
      : index(_index), first_class(-1), 
deba@2548
  1283
	first_free_class(-1), first_free_node(-1) {}
deba@2548
  1284
deba@2548
  1285
    /// \brief Insert a new node into a new component.
deba@2548
  1286
    ///
deba@2548
  1287
    /// Insert a new node into a new component.
deba@2548
  1288
    /// \param item The item of the new node.
deba@2548
  1289
    /// \param prio The priority of the new node.
deba@2548
  1290
    /// \return The class id of the one-item-heap.
deba@2548
  1291
    int insert(const Item& item, const Value& prio) {
deba@2548
  1292
      int id = newNode();
deba@2548
  1293
      nodes[id].item = item;
deba@2548
  1294
      nodes[id].prio = prio;
deba@2548
  1295
      nodes[id].size = 0;
deba@2548
  1296
deba@2548
  1297
      nodes[id].prev = -1;
deba@2548
  1298
      nodes[id].next = -1;
deba@2548
  1299
deba@2548
  1300
      nodes[id].left = -1;
deba@2548
  1301
      nodes[id].right = -1;
deba@2548
  1302
deba@2548
  1303
      nodes[id].item = item;
deba@2548
  1304
      index[item] = id;
deba@2548
  1305
      
deba@2548
  1306
      int class_id = newClass();
deba@2548
  1307
      classes[class_id].parent = ~id;
deba@2548
  1308
      classes[class_id].depth = 0;
deba@2548
  1309
deba@2548
  1310
      classes[class_id].left = -1;
deba@2548
  1311
      classes[class_id].right = -1;
deba@2548
  1312
      
deba@2548
  1313
      if (first_class != -1) {
deba@2548
  1314
        classes[first_class].prev = class_id;
deba@2548
  1315
      }
deba@2548
  1316
      classes[class_id].next = first_class;
deba@2548
  1317
      classes[class_id].prev = -1;
deba@2548
  1318
      first_class = class_id;
deba@2548
  1319
deba@2548
  1320
      nodes[id].parent = ~class_id;
deba@2548
  1321
      
deba@2548
  1322
      return class_id;
deba@2548
  1323
    }
deba@2548
  1324
deba@2548
  1325
    /// \brief The class of the item.
deba@2548
  1326
    ///
deba@2548
  1327
    /// \return The alive class id of the item, which is not nested into
deba@2548
  1328
    /// other classes.
deba@2548
  1329
    ///
deba@2548
  1330
    /// The time complexity is O(log(n)).
deba@2548
  1331
    int find(const Item& item) const {
deba@2548
  1332
      return findClass(index[item]);
deba@2548
  1333
    }
deba@2548
  1334
    
deba@2548
  1335
    /// \brief Joins the classes.
deba@2548
  1336
    ///
deba@2548
  1337
    /// The current function joins the given classes. The parameter is
deba@2548
  1338
    /// an STL range which should be contains valid class ids. The
deba@2548
  1339
    /// time complexity is O(log(n)*k) where n is the overall number
deba@2548
  1340
    /// of the joined nodes and k is the number of classes.
deba@2548
  1341
    /// \return The class of the joined classes.
deba@2548
  1342
    /// \pre The range should contain at least two class ids.
deba@2548
  1343
    template <typename Iterator>
deba@2548
  1344
    int join(Iterator begin, Iterator end) {
deba@2548
  1345
      std::vector<int> cs;
deba@2548
  1346
      for (Iterator it = begin; it != end; ++it) {
deba@2548
  1347
        cs.push_back(*it);
deba@2548
  1348
      }
deba@2548
  1349
deba@2548
  1350
      int class_id = newClass();
deba@2548
  1351
      { // creation union-find
deba@2548
  1352
deba@2548
  1353
        if (first_class != -1) {
deba@2548
  1354
          classes[first_class].prev = class_id;
deba@2548
  1355
        }
deba@2548
  1356
        classes[class_id].next = first_class;
deba@2548
  1357
        classes[class_id].prev = -1;
deba@2548
  1358
        first_class = class_id;
deba@2548
  1359
deba@2548
  1360
        classes[class_id].depth = classes[cs[0]].depth;
deba@2548
  1361
        classes[class_id].parent = classes[cs[0]].parent;
deba@2548
  1362
        nodes[~(classes[class_id].parent)].parent = ~class_id;
deba@2548
  1363
deba@2548
  1364
        int l = cs[0];
deba@2548
  1365
deba@2548
  1366
        classes[class_id].left = l;
deba@2548
  1367
        classes[class_id].right = l;
deba@2548
  1368
deba@2548
  1369
        if (classes[l].next != -1) {
deba@2548
  1370
          classes[classes[l].next].prev = classes[l].prev;
deba@2548
  1371
        }
deba@2548
  1372
        classes[classes[l].prev].next = classes[l].next;
deba@2548
  1373
        
deba@2548
  1374
        classes[l].prev = -1;
deba@2548
  1375
        classes[l].next = -1;
deba@2548
  1376
deba@2548
  1377
        classes[l].depth = leftNode(l);
deba@2548
  1378
        classes[l].parent = class_id;
deba@2548
  1379
        
deba@2548
  1380
      }
deba@2548
  1381
deba@2548
  1382
      { // merging of heap
deba@2548
  1383
        int l = class_id;
deba@2548
  1384
        for (int ci = 1; ci < int(cs.size()); ++ci) {
deba@2548
  1385
          int r = cs[ci];
deba@2548
  1386
          int rln = leftNode(r);
deba@2548
  1387
          if (classes[l].depth > classes[r].depth) {
deba@2548
  1388
            int id = ~(classes[l].parent);
deba@2548
  1389
            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
deba@2548
  1390
              id = nodes[id].right;
deba@2548
  1391
            }
deba@2548
  1392
            while (id >= 0 && nodes[id].size == cmax) {
deba@2548
  1393
              int new_id = newNode();
deba@2548
  1394
              int right_id = nodes[id].right;
deba@2548
  1395
deba@2548
  1396
              popRight(id);
deba@2548
  1397
              if (nodes[id].item == nodes[right_id].item) {
deba@2548
  1398
                setPrio(id);
deba@2548
  1399
              }
deba@2548
  1400
              push(new_id, right_id);
deba@2548
  1401
              pushRight(new_id, ~(classes[r].parent));
deba@2548
  1402
              setPrio(new_id);
deba@2548
  1403
deba@2548
  1404
              id = nodes[id].parent;
deba@2548
  1405
              classes[r].parent = ~new_id;
deba@2548
  1406
            }
deba@2548
  1407
            if (id < 0) {
deba@2548
  1408
              int new_parent = newNode();
deba@2548
  1409
              nodes[new_parent].next = -1;
deba@2548
  1410
              nodes[new_parent].prev = -1;
deba@2548
  1411
              nodes[new_parent].parent = ~l;
deba@2548
  1412
deba@2548
  1413
              push(new_parent, ~(classes[l].parent));
deba@2548
  1414
              pushRight(new_parent, ~(classes[r].parent));
deba@2548
  1415
              setPrio(new_parent);
deba@2548
  1416
deba@2548
  1417
              classes[l].parent = ~new_parent;
deba@2548
  1418
              classes[l].depth += 1;
deba@2548
  1419
            } else {
deba@2548
  1420
              pushRight(id, ~(classes[r].parent));
deba@2548
  1421
              while (id >= 0 && less(~(classes[r].parent), id)) {
deba@2548
  1422
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
deba@2548
  1423
                nodes[id].item = nodes[~(classes[r].parent)].item;
deba@2548
  1424
                id = nodes[id].parent;
deba@2548
  1425
              }
deba@2548
  1426
            }
deba@2548
  1427
          } else if (classes[r].depth > classes[l].depth) {
deba@2548
  1428
            int id = ~(classes[r].parent);
deba@2548
  1429
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
deba@2548
  1430
              id = nodes[id].left;
deba@2548
  1431
            }
deba@2548
  1432
            while (id >= 0 && nodes[id].size == cmax) {
deba@2548
  1433
              int new_id = newNode();
deba@2548
  1434
              int left_id = nodes[id].left;
deba@2548
  1435
deba@2548
  1436
              popLeft(id);
deba@2548
  1437
              if (nodes[id].prio == nodes[left_id].prio) {
deba@2548
  1438
                setPrio(id);
deba@2548
  1439
              }
deba@2548
  1440
              push(new_id, left_id);
deba@2548
  1441
              pushLeft(new_id, ~(classes[l].parent));
deba@2548
  1442
              setPrio(new_id);
deba@2548
  1443
deba@2548
  1444
              id = nodes[id].parent;
deba@2548
  1445
              classes[l].parent = ~new_id;
deba@2548
  1446
deba@2548
  1447
            }
deba@2548
  1448
            if (id < 0) {
deba@2548
  1449
              int new_parent = newNode();
deba@2548
  1450
              nodes[new_parent].next = -1;
deba@2548
  1451
              nodes[new_parent].prev = -1;
deba@2548
  1452
              nodes[new_parent].parent = ~l;
deba@2548
  1453
deba@2548
  1454
              push(new_parent, ~(classes[r].parent));
deba@2548
  1455
              pushLeft(new_parent, ~(classes[l].parent));
deba@2548
  1456
              setPrio(new_parent);
deba@2548
  1457
              
deba@2548
  1458
              classes[r].parent = ~new_parent;
deba@2548
  1459
              classes[r].depth += 1;
deba@2548
  1460
            } else {
deba@2548
  1461
              pushLeft(id, ~(classes[l].parent));
deba@2548
  1462
              while (id >= 0 && less(~(classes[l].parent), id)) {
deba@2548
  1463
                nodes[id].prio = nodes[~(classes[l].parent)].prio;
deba@2548
  1464
                nodes[id].item = nodes[~(classes[l].parent)].item;
deba@2548
  1465
                id = nodes[id].parent;
deba@2548
  1466
              }
deba@2548
  1467
            }
deba@2548
  1468
            nodes[~(classes[r].parent)].parent = ~l;
deba@2548
  1469
            classes[l].parent = classes[r].parent;
deba@2548
  1470
            classes[l].depth = classes[r].depth;
deba@2548
  1471
          } else {
deba@2548
  1472
            if (classes[l].depth != 0 && 
deba@2548
  1473
                nodes[~(classes[l].parent)].size + 
deba@2548
  1474
                nodes[~(classes[r].parent)].size <= cmax) {
deba@2548
  1475
              splice(~(classes[l].parent), ~(classes[r].parent));
deba@2548
  1476
              deleteNode(~(classes[r].parent));
deba@2548
  1477
              if (less(~(classes[r].parent), ~(classes[l].parent))) {
deba@2548
  1478
                nodes[~(classes[l].parent)].prio = 
deba@2548
  1479
                  nodes[~(classes[r].parent)].prio;
deba@2548
  1480
                nodes[~(classes[l].parent)].item = 
deba@2548
  1481
                  nodes[~(classes[r].parent)].item;
deba@2548
  1482
              }
deba@2548
  1483
            } else {
deba@2548
  1484
              int new_parent = newNode();
deba@2548
  1485
              nodes[new_parent].next = nodes[new_parent].prev = -1;
deba@2548
  1486
              push(new_parent, ~(classes[l].parent));
deba@2548
  1487
              pushRight(new_parent, ~(classes[r].parent));
deba@2548
  1488
              setPrio(new_parent);
deba@2548
  1489
            
deba@2548
  1490
              classes[l].parent = ~new_parent;
deba@2548
  1491
              classes[l].depth += 1;
deba@2548
  1492
              nodes[new_parent].parent = ~l;
deba@2548
  1493
            }
deba@2548
  1494
          }
deba@2548
  1495
          if (classes[r].next != -1) {
deba@2548
  1496
            classes[classes[r].next].prev = classes[r].prev;
deba@2548
  1497
          }
deba@2548
  1498
          classes[classes[r].prev].next = classes[r].next;
deba@2548
  1499
deba@2548
  1500
          classes[r].prev = classes[l].right;
deba@2548
  1501
          classes[classes[l].right].next = r;
deba@2548
  1502
          classes[l].right = r;
deba@2548
  1503
          classes[r].parent = l;
deba@2548
  1504
deba@2548
  1505
          classes[r].next = -1;
deba@2548
  1506
          classes[r].depth = rln;
deba@2548
  1507
        }
deba@2548
  1508
      }
deba@2548
  1509
      return class_id;
deba@2548
  1510
    }
deba@2548
  1511
deba@2548
  1512
    /// \brief Split the class to subclasses.
deba@2548
  1513
    ///
deba@2548
  1514
    /// The current function splits the given class. The join, which
deba@2548
  1515
    /// made the current class, stored a reference to the
deba@2548
  1516
    /// subclasses. The \c splitClass() member restores the classes
deba@2548
  1517
    /// and creates the heaps. The parameter is an STL output iterator
deba@2548
  1518
    /// which will be filled with the subclass ids. The time
deba@2548
  1519
    /// complexity is O(log(n)*k) where n is the overall number of
deba@2548
  1520
    /// nodes in the splitted classes and k is the number of the
deba@2548
  1521
    /// classes.
deba@2548
  1522
    template <typename Iterator>
deba@2548
  1523
    void split(int cls, Iterator out) {
deba@2548
  1524
      std::vector<int> cs;
deba@2548
  1525
      { // splitting union-find
deba@2548
  1526
        int id = cls;
deba@2548
  1527
        int l = classes[id].left;
deba@2548
  1528
deba@2548
  1529
        classes[l].parent = classes[id].parent;
deba@2548
  1530
        classes[l].depth = classes[id].depth;
deba@2548
  1531
deba@2548
  1532
        nodes[~(classes[l].parent)].parent = ~l;
deba@2548
  1533
deba@2548
  1534
        *out++ = l;
deba@2548
  1535
deba@2548
  1536
        while (l != -1) {
deba@2548
  1537
          cs.push_back(l);
deba@2548
  1538
          l = classes[l].next;
deba@2548
  1539
        }
deba@2548
  1540
deba@2548
  1541
        classes[classes[id].right].next = first_class;
deba@2548
  1542
        classes[first_class].prev = classes[id].right;
deba@2548
  1543
        first_class = classes[id].left;
deba@2548
  1544
        
deba@2548
  1545
        if (classes[id].next != -1) {
deba@2548
  1546
          classes[classes[id].next].prev = classes[id].prev;
deba@2548
  1547
        }
deba@2548
  1548
        classes[classes[id].prev].next = classes[id].next;
deba@2548
  1549
        
deba@2548
  1550
        deleteClass(id);
deba@2548
  1551
      }
deba@2548
  1552
deba@2548
  1553
      {
deba@2548
  1554
        for (int i = 1; i < int(cs.size()); ++i) {
deba@2548
  1555
          int l = classes[cs[i]].depth;
deba@2548
  1556
          while (nodes[nodes[l].parent].left == l) {
deba@2548
  1557
            l = nodes[l].parent;
deba@2548
  1558
          }
deba@2548
  1559
          int r = l;    
deba@2548
  1560
          while (nodes[l].parent >= 0) {
deba@2548
  1561
            l = nodes[l].parent;
deba@2548
  1562
            int new_node = newNode();
deba@2548
  1563
deba@2548
  1564
            nodes[new_node].prev = -1;
deba@2548
  1565
            nodes[new_node].next = -1;
deba@2548
  1566
deba@2548
  1567
            split(r, new_node);
deba@2548
  1568
            pushAfter(l, new_node);
deba@2548
  1569
            setPrio(l);
deba@2548
  1570
            setPrio(new_node);
deba@2548
  1571
            r = new_node;
deba@2548
  1572
          }
deba@2548
  1573
          classes[cs[i]].parent = ~r;
deba@2548
  1574
          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
deba@2548
  1575
          nodes[r].parent = ~cs[i];
deba@2548
  1576
deba@2548
  1577
          nodes[l].next = -1;
deba@2548
  1578
          nodes[r].prev = -1;
deba@2548
  1579
deba@2548
  1580
          repairRight(~(nodes[l].parent));
deba@2548
  1581
          repairLeft(cs[i]);
deba@2548
  1582
          
deba@2548
  1583
          *out++ = cs[i];
deba@2548
  1584
        }
deba@2548
  1585
      }
deba@2548
  1586
    }
deba@2548
  1587
deba@2548
  1588
    /// \brief Gives back the priority of the current item.
deba@2548
  1589
    ///
deba@2548
  1590
    /// \return Gives back the priority of the current item.
deba@2548
  1591
    const Value& operator[](const Item& item) const {
deba@2548
  1592
      return nodes[index[item]].prio;
deba@2548
  1593
    }
deba@2548
  1594
deba@2548
  1595
    /// \brief Sets the priority of the current item.
deba@2548
  1596
    ///
deba@2548
  1597
    /// Sets the priority of the current item.
deba@2548
  1598
    void set(const Item& item, const Value& prio) {
deba@2548
  1599
      if (comp(prio, nodes[index[item]].prio)) {
deba@2548
  1600
        decrease(item, prio);
deba@2548
  1601
      } else if (!comp(prio, nodes[index[item]].prio)) {
deba@2548
  1602
        increase(item, prio);
deba@2548
  1603
      }
deba@2548
  1604
    }
deba@2548
  1605
      
deba@2548
  1606
    /// \brief Increase the priority of the current item.
deba@2548
  1607
    ///
deba@2548
  1608
    /// Increase the priority of the current item.
deba@2548
  1609
    void increase(const Item& item, const Value& prio) {
deba@2548
  1610
      int id = index[item];
deba@2548
  1611
      int kd = nodes[id].parent;
deba@2548
  1612
      nodes[id].prio = prio;
deba@2548
  1613
      while (kd >= 0 && nodes[kd].item == item) {
deba@2548
  1614
        setPrio(kd);
deba@2548
  1615
        kd = nodes[kd].parent;
deba@2548
  1616
      }
deba@2548
  1617
    }
deba@2548
  1618
deba@2548
  1619
    /// \brief Increase the priority of the current item.
deba@2548
  1620
    ///
deba@2548
  1621
    /// Increase the priority of the current item.
deba@2548
  1622
    void decrease(const Item& item, const Value& prio) {
deba@2548
  1623
      int id = index[item];
deba@2548
  1624
      int kd = nodes[id].parent;
deba@2548
  1625
      nodes[id].prio = prio;
deba@2548
  1626
      while (kd >= 0 && less(id, kd)) {
deba@2548
  1627
        nodes[kd].prio = prio;
deba@2548
  1628
        nodes[kd].item = item;
deba@2548
  1629
        kd = nodes[kd].parent;
deba@2548
  1630
      }
deba@2548
  1631
    }
deba@2548
  1632
    
deba@2548
  1633
    /// \brief Gives back the minimum priority of the class.
deba@2548
  1634
    ///
deba@2548
  1635
    /// \return Gives back the minimum priority of the class.
deba@2548
  1636
    const Value& classPrio(int cls) const {
deba@2548
  1637
      return nodes[~(classes[cls].parent)].prio;
deba@2548
  1638
    }
deba@2548
  1639
deba@2548
  1640
    /// \brief Gives back the minimum priority item of the class.
deba@2548
  1641
    ///
deba@2548
  1642
    /// \return Gives back the minimum priority item of the class.
deba@2548
  1643
    const Item& classTop(int cls) const {
deba@2548
  1644
      return nodes[~(classes[cls].parent)].item;
deba@2548
  1645
    }
deba@2548
  1646
deba@2548
  1647
    /// \brief Gives back a representant item of the class.
deba@2548
  1648
    /// 
deba@2548
  1649
    /// The representant is indpendent from the priorities of the
deba@2548
  1650
    /// items. 
deba@2548
  1651
    /// \return Gives back a representant item of the class.
deba@2548
  1652
    const Item& classRep(int id) const {
deba@2548
  1653
      int parent = classes[id].parent;
deba@2548
  1654
      return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
deba@2548
  1655
    }
deba@2548
  1656
deba@2548
  1657
    /// \brief Lemon style iterator for the items of a class.
deba@2548
  1658
    ///
deba@2548
  1659
    /// ClassIt is a lemon style iterator for the components. It iterates
deba@2548
  1660
    /// on the items of a class. By example if you want to iterate on
deba@2548
  1661
    /// each items of each classes then you may write the next code.
deba@2548
  1662
    ///\code
deba@2548
  1663
    /// for (ClassIt cit(huf); cit != INVALID; ++cit) {
deba@2548
  1664
    ///   std::cout << "Class: ";
deba@2548
  1665
    ///   for (ItemIt iit(huf, cit); iit != INVALID; ++iit) {
deba@2548
  1666
    ///     std::cout << toString(iit) << ' ' << std::endl;
deba@2548
  1667
    ///   }
deba@2548
  1668
    ///   std::cout << std::endl;
deba@2548
  1669
    /// }
deba@2548
  1670
    ///\endcode
deba@2548
  1671
    class ItemIt {
deba@2548
  1672
    private:
deba@2548
  1673
deba@2548
  1674
      const HeapUnionFind* _huf;
deba@2548
  1675
      int _id, _lid;
deba@2548
  1676
      
deba@2548
  1677
    public:
deba@2548
  1678
deba@2548
  1679
      /// \brief Default constructor 
deba@2548
  1680
      ///
deba@2548
  1681
      /// Default constructor 
deba@2548
  1682
      ItemIt() {}
deba@2548
  1683
deba@2548
  1684
      ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) {
deba@2548
  1685
        int id = cls;
deba@2548
  1686
        int parent = _huf->classes[id].parent;
deba@2548
  1687
        if (parent >= 0) {
deba@2548
  1688
          _id = _huf->classes[id].depth;
deba@2548
  1689
          if (_huf->classes[id].next != -1) {
deba@2548
  1690
            _lid = _huf->classes[_huf->classes[id].next].depth;
deba@2548
  1691
          } else {
deba@2548
  1692
            _lid = -1;
deba@2548
  1693
          }
deba@2548
  1694
        } else {
deba@2548
  1695
          _id = _huf->leftNode(id);
deba@2548
  1696
          _lid = -1;
deba@2548
  1697
        } 
deba@2548
  1698
      }
deba@2548
  1699
      
deba@2548
  1700
      /// \brief Increment operator
deba@2548
  1701
      ///
deba@2548
  1702
      /// It steps to the next item in the class.
deba@2548
  1703
      ItemIt& operator++() {
deba@2548
  1704
        _id = _huf->nextNode(_id);
deba@2548
  1705
        return *this;
deba@2548
  1706
      }
deba@2548
  1707
deba@2548
  1708
      /// \brief Conversion operator
deba@2548
  1709
      ///
deba@2548
  1710
      /// It converts the iterator to the current item.
deba@2548
  1711
      operator const Item&() const {
deba@2548
  1712
        return _huf->nodes[_id].item;
deba@2548
  1713
      }
deba@2548
  1714
      
deba@2548
  1715
      /// \brief Equality operator
deba@2548
  1716
      ///
deba@2548
  1717
      /// Equality operator
deba@2548
  1718
      bool operator==(const ItemIt& i) { 
deba@2548
  1719
        return i._id == _id;
deba@2548
  1720
      }
deba@2548
  1721
deba@2548
  1722
      /// \brief Inequality operator
deba@2548
  1723
      ///
deba@2548
  1724
      /// Inequality operator
deba@2548
  1725
      bool operator!=(const ItemIt& i) { 
deba@2548
  1726
        return i._id != _id;
deba@2548
  1727
      }
deba@2548
  1728
deba@2548
  1729
      /// \brief Equality operator
deba@2548
  1730
      ///
deba@2548
  1731
      /// Equality operator
deba@2548
  1732
      bool operator==(Invalid) { 
deba@2548
  1733
        return _id == _lid;
deba@2548
  1734
      }
deba@2548
  1735
deba@2548
  1736
      /// \brief Inequality operator
deba@2548
  1737
      ///
deba@2548
  1738
      /// Inequality operator
deba@2548
  1739
      bool operator!=(Invalid) { 
deba@2548
  1740
        return _id != _lid;
deba@2548
  1741
      }
deba@2548
  1742
      
deba@2548
  1743
    };
deba@2548
  1744
deba@2548
  1745
    /// \brief Class iterator
deba@2548
  1746
    ///
deba@2548
  1747
    /// The iterator stores 
deba@2548
  1748
    class ClassIt {
deba@2548
  1749
    private:
deba@2548
  1750
deba@2548
  1751
      const HeapUnionFind* _huf;
deba@2548
  1752
      int _id;
deba@2548
  1753
deba@2548
  1754
    public:
deba@2548
  1755
deba@2548
  1756
      ClassIt(const HeapUnionFind& huf) 
deba@2548
  1757
        : _huf(&huf), _id(huf.first_class) {}
deba@2548
  1758
deba@2548
  1759
      ClassIt(const HeapUnionFind& huf, int cls) 
deba@2548
  1760
        : _huf(&huf), _id(huf.classes[cls].left) {}
deba@2548
  1761
deba@2548
  1762
      ClassIt(Invalid) : _huf(0), _id(-1) {}
deba@2548
  1763
      
deba@2548
  1764
      const ClassIt& operator++() {
deba@2548
  1765
        _id = _huf->classes[_id].next;
deba@2548
  1766
	return *this;
deba@2548
  1767
      }
deba@2548
  1768
deba@2548
  1769
      /// \brief Equality operator
deba@2548
  1770
      ///
deba@2548
  1771
      /// Equality operator
deba@2548
  1772
      bool operator==(const ClassIt& i) { 
deba@2548
  1773
        return i._id == _id;
deba@2548
  1774
      }
deba@2548
  1775
deba@2548
  1776
      /// \brief Inequality operator
deba@2548
  1777
      ///
deba@2548
  1778
      /// Inequality operator
deba@2548
  1779
      bool operator!=(const ClassIt& i) { 
deba@2548
  1780
        return i._id != _id;
deba@2548
  1781
      }      
deba@2548
  1782
      
deba@2548
  1783
      operator int() const {
deba@2548
  1784
	return _id;
deba@2548
  1785
      }
deba@2548
  1786
            
deba@2548
  1787
    };
deba@2548
  1788
deba@2548
  1789
  };
deba@2548
  1790
beckerjc@483
  1791
  //! @}
beckerjc@483
  1792
alpar@921
  1793
} //namespace lemon
beckerjc@483
  1794
alpar@921
  1795
#endif //LEMON_UNION_FIND_H