lemon/dynamic_tree.h
author deba
Mon, 17 Dec 2007 09:54:26 +0000
changeset 2542 faaa54ec4520
parent 2514 57143c09dc20
child 2553 bfced05fa852
permissions -rw-r--r--
Bug fix
deba@2514
     1
/* -*- C++ -*-
deba@2514
     2
 *
deba@2514
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2514
     4
 *
deba@2514
     5
 * Copyright (C) 2003-2007
deba@2514
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2514
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2514
     8
 *
deba@2514
     9
 * Permission to use, modify and distribute this software is granted
deba@2514
    10
 * provided that this copyright notice appears in all copies. For
deba@2514
    11
 * precise terms see the accompanying LICENSE file.
deba@2514
    12
 *
deba@2514
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2514
    14
 * express or implied, and with no claim as to its suitability for any
deba@2514
    15
 * purpose.
deba@2514
    16
 *
deba@2514
    17
 */
deba@2514
    18
#ifndef LEMON_DYNAMIC_TREE_H
deba@2514
    19
#define LEMON_DYNAMIC_TREE_H
deba@2514
    20
deba@2514
    21
/// \ingroup auxdata
deba@2514
    22
/// \file
deba@2514
    23
/// \brief The dynamic tree data structure of Sleator and Tarjan.
deba@2514
    24
///
deba@2514
    25
deba@2514
    26
#include <vector>
deba@2514
    27
#include <limits>
deba@2514
    28
#include <lemon/tolerance.h>
deba@2514
    29
deba@2514
    30
namespace lemon {
deba@2514
    31
deba@2514
    32
  /// \ingroup auxdata
deba@2514
    33
  ///
deba@2514
    34
  /// \brief The dynamic tree data structure of Sleator and Tarjan.
deba@2514
    35
  ///
deba@2514
    36
  /// This class provides an implementation of the dynamic tree data
deba@2514
    37
  /// structure for maintaining a set of node-disjoint rooted
deba@2514
    38
  /// trees. Each item has an associated value, and the item with
deba@2514
    39
  /// minimum value can be find in \f$O(\log(n)\f$ on the path from a
deba@2514
    40
  /// node to the its root, and the items on such path can be
deba@2514
    41
  /// increased or decreased globally with a certain value in the same
deba@2514
    42
  /// running time. We regard a tree edge as directed toward the root,
deba@2514
    43
  /// that is from child to parent. Its structure can be modified by
deba@2514
    44
  /// two basic operations: \e link(v,w) adds an edge between a root v
deba@2514
    45
  /// and a node w in a different component; \e cut(v) removes the
deba@2514
    46
  /// edge between v and its parent.
deba@2514
    47
  /// 
deba@2514
    48
  /// \param _Value The value type of the items.  
deba@2514
    49
  /// \param _ItemIntMap Converts item type of node to integer.
deba@2514
    50
  /// \param _Tolerance The tolerance class to handle computation
deba@2514
    51
  /// problems.
deba@2514
    52
  /// \param _enableSize If true then the data structre manatain the
deba@2514
    53
  /// size of each tree. The feature is used in \ref GoldbergTarjan
deba@2514
    54
  /// algorithm. The default value is true.
deba@2514
    55
  ///
deba@2514
    56
  /// \author Hamori Tamas
deba@2514
    57
#ifdef DOXYGEN
deba@2514
    58
  template <typename _Value, typename _ItemIntMap, 
deba@2514
    59
	    typename _Tolerance, bool _enableSize>
deba@2514
    60
#else
deba@2514
    61
  template <typename _Value, typename _ItemIntMap, 
deba@2514
    62
	    typename _Tolerance = lemon::Tolerance<_Value>,
deba@2514
    63
	    bool _enableSize = true>
deba@2514
    64
#endif
deba@2514
    65
  class DynamicTree {
deba@2514
    66
  public:
deba@2514
    67
    /// \brief The integer map on the items.
deba@2514
    68
    typedef _ItemIntMap ItemIntMap;
deba@2514
    69
    /// \brief The item type of nodes.
deba@2514
    70
    typedef typename ItemIntMap::Key Item;
deba@2514
    71
    /// \brief The value type of the algorithms.
deba@2514
    72
    typedef _Value Value;
deba@2514
    73
    /// \brief The tolerance used by the algorithm.
deba@2514
    74
    typedef _Tolerance Tolerance;
deba@2514
    75
deba@2514
    76
  private:
deba@2514
    77
  
deba@2514
    78
    class ItemData;
deba@2514
    79
deba@2514
    80
    std::vector<ItemData> _data;
deba@2514
    81
    ItemIntMap &_iim;
deba@2514
    82
    Value _max_value;
deba@2514
    83
    Tolerance _tolerance;
deba@2514
    84
deba@2514
    85
  public:
deba@2514
    86
    /// \brief The constructor of the class.
deba@2514
    87
    ///
deba@2514
    88
    /// \param iim The integer map on the items. 
deba@2514
    89
    /// \param tolerance Tolerance class.
deba@2514
    90
    DynamicTree(ItemIntMap &iim, const Tolerance& tolerance = Tolerance())
deba@2514
    91
      : _iim(iim), _max_value(std::numeric_limits<Value>::max()), 
deba@2514
    92
	_tolerance(tolerance) {}
deba@2514
    93
  
deba@2514
    94
    ~DynamicTree() {}
deba@2514
    95
deba@2514
    96
    /// \brief Clears the data structure
deba@2514
    97
    ///
deba@2514
    98
    /// Clears the data structure
deba@2514
    99
    void clear() {
deba@2514
   100
      _data.clear();
deba@2514
   101
    }
deba@2514
   102
deba@2514
   103
    /// \brief Sets the tolerance used by algorithm.
deba@2514
   104
    ///
deba@2514
   105
    /// Sets the tolerance used by algorithm.
deba@2514
   106
    void tolerance(const Tolerance& tolerance) const {
deba@2514
   107
      _tolerance = tolerance;
deba@2514
   108
      return *this;
deba@2514
   109
    } 
deba@2514
   110
  
deba@2514
   111
    /// \brief Returns the tolerance used by algorithm.
deba@2514
   112
    ///
deba@2514
   113
    /// Returns the tolerance used by algorithm.
deba@2514
   114
    const Tolerance& tolerance() const {
deba@2514
   115
      return tolerance;
deba@2514
   116
    } 
deba@2514
   117
  
deba@2514
   118
    /// \brief Create a new tree containing a single node with cost zero.
deba@2514
   119
    void makeTree(const Item &item) {
deba@2514
   120
      _data[makePath(item)].successor = -1;
deba@2514
   121
    }
deba@2514
   122
    
deba@2514
   123
    /// \brief Return the root of the tree containing node with itemtype
deba@2514
   124
    /// \e item.
deba@2514
   125
    Item findRoot(const Item &item) {
deba@2514
   126
      return _data[findTail(expose(_iim[item]))].id;
deba@2514
   127
    }
deba@2514
   128
    
deba@2514
   129
    /// \brief Return the the value of nodes in the tree containing
deba@2514
   130
    /// node with itemtype \e item.
deba@2514
   131
    int findSize(const Item &item) {
deba@2514
   132
      return _data[expose(_iim[item])].size;
deba@2514
   133
    }
deba@2514
   134
    
deba@2514
   135
    /// \brief Return the minimum cost containing node.
deba@2514
   136
    /// 
deba@2514
   137
    /// Return into \e d the minimum cost on the tree path from \e item
deba@2514
   138
    /// to findRoot(item).  Return the last item (closest to its root)
deba@2514
   139
    /// on this path of the minimum cost.
deba@2514
   140
    Item findCost(const Item &item, Value& d){
deba@2514
   141
      return _data[findPathCost(expose(_iim[item]),d)].id;
deba@2514
   142
    }
deba@2514
   143
    
deba@2514
   144
    /// \brief Add \e x value to the cost of every node on the path from
deba@2514
   145
    /// \e item to findRoot(item).
deba@2519
   146
    void addCost(const Item &item, Value x) {
deba@2514
   147
      addPathCost(expose(_iim[item]), x);
deba@2514
   148
    }
deba@2514
   149
    
deba@2514
   150
    /// \brief Combine the trees containing nodes \e item1 and \e item2
deba@2514
   151
    /// by adding an edge from \e item1 \e item2.
deba@2514
   152
    /// 
deba@2514
   153
    /// This operation assumes that \e item1 is root and \e item2 is in
deba@2514
   154
    /// a different tree.
deba@2514
   155
    void link(const Item &item1, const Item &item2){
deba@2514
   156
      int v = _iim[item1];
deba@2514
   157
      int w = _iim[item2];
deba@2514
   158
      int p = expose(w);
deba@2514
   159
      join(-1, expose(v), p);
deba@2514
   160
      _data[v].successor = -1;
deba@2514
   161
      _data[v].size += _data[p].size;
deba@2514
   162
deba@2514
   163
    }    
deba@2514
   164
    
deba@2514
   165
    /// \brief Divide the tree containing node \e item into two trees by
deba@2514
   166
    /// deleting the edge out of \e item.
deba@2514
   167
    /// 
deba@2514
   168
    /// This operation assumes that \e item is not a tree root.
deba@2514
   169
    void cut(const Item &item) {
deba@2514
   170
      int v = _iim[item];
deba@2514
   171
      int p, q;
deba@2514
   172
      expose(v);
deba@2514
   173
      split(p, v, q);
deba@2514
   174
      if (p != -1) {
deba@2514
   175
	_data[p].successor = v;
deba@2514
   176
      }
deba@2514
   177
      _data[v].size -= _data[q].size;
deba@2514
   178
      if (q != -1) {
deba@2514
   179
	_data[q].successor = _data[v].successor;
deba@2514
   180
      }
deba@2514
   181
      _data[v].successor = -1;
deba@2514
   182
    }
deba@2514
   183
deba@2514
   184
    ///\brief 
deba@2514
   185
    Item parent(const Item &item){
deba@2514
   186
      return _data[_iim[item].p].id;
deba@2514
   187
    }
deba@2514
   188
deba@2514
   189
    ///\brief Return the upper bound of the costs.
deba@2514
   190
    Value maxValue() const {
deba@2514
   191
      return _max_value;
deba@2514
   192
    }
deba@2514
   193
    
deba@2514
   194
  private:
deba@2514
   195
deba@2514
   196
    int makePath(const Item &item) {
deba@2514
   197
      _iim.set(item, _data.size());
deba@2514
   198
      ItemData v(item);
deba@2514
   199
      _data.push_back(v);
deba@2514
   200
      return _iim[item];
deba@2514
   201
    }
deba@2514
   202
deba@2519
   203
    int findPath(int v) {
deba@2514
   204
      splay(v);
deba@2514
   205
      return v;
deba@2514
   206
    }
deba@2514
   207
    
deba@2519
   208
    int findPathCost(int p, Value &d) {
deba@2514
   209
      while ((_data[p].right != -1 && 
deba@2514
   210
	      !_tolerance.less(0, _data[_data[p].right].dmin)) || 
deba@2514
   211
	     (_data[p].left != -1 && _tolerance.less(0, _data[p].dcost))) {
deba@2514
   212
	if (_data[p].right != -1 && 
deba@2514
   213
	    !_tolerance.less(0, _data[_data[p].right].dmin)) {
deba@2514
   214
	  p = _data[p].right;
deba@2514
   215
	} else if (_data[p].left != -1 && 
deba@2519
   216
		   !_tolerance.less(0, _data[_data[p].left].dmin)) {
deba@2514
   217
	  p = _data[p].left;
deba@2514
   218
	}
deba@2514
   219
      }
deba@2514
   220
      splay(p);
deba@2514
   221
      d = _data[p].dmin;
deba@2514
   222
      return p; 
deba@2514
   223
    }
deba@2514
   224
deba@2514
   225
    int findTail(int p){
deba@2514
   226
      while (_data[p].right != -1) {
deba@2514
   227
	p = _data[p].right;
deba@2514
   228
      }
deba@2514
   229
      splay(p);
deba@2514
   230
      return p;
deba@2514
   231
    }
deba@2514
   232
    
deba@2519
   233
    void addPathCost(int p, Value x) {
deba@2514
   234
      if (!_tolerance.less(x, _max_value)) {
deba@2519
   235
	_data[p].dmin = x;
deba@2519
   236
	_data[p].dcost = x;
deba@2514
   237
      } else if (!_tolerance.less(-x, _max_value)) {
deba@2514
   238
	_data[p].dmin = 0;
deba@2514
   239
	_data[p].dcost = 0;
deba@2514
   240
      } else {
deba@2514
   241
	_data[p].dmin += x;
deba@2514
   242
      }
deba@2514
   243
    }
deba@2514
   244
deba@2514
   245
    void join(int p, int v, int q) {
deba@2514
   246
      Value min = _max_value;
deba@2514
   247
      Value pmin = _max_value;
deba@2514
   248
      Value vmin = _data[v].dmin;
deba@2514
   249
      Value qmin = _max_value;
deba@2514
   250
      if (p != -1){
deba@2514
   251
	pmin = _data[p].dmin;
deba@2514
   252
      }
deba@2514
   253
      if (q != -1){
deba@2514
   254
	qmin = _data[q].dmin;
deba@2514
   255
      }
deba@2514
   256
        
deba@2514
   257
      if (_tolerance.less(vmin, qmin)) {
deba@2514
   258
	if (_tolerance.less(vmin,pmin)) {
deba@2514
   259
	  min = vmin;
deba@2514
   260
	} else {
deba@2514
   261
	  min = pmin;
deba@2514
   262
	}
deba@2514
   263
      } else if (_tolerance.less(qmin,pmin)) {
deba@2514
   264
	min = qmin;
deba@2514
   265
      } else {
deba@2514
   266
	min = pmin;
deba@2514
   267
      }
deba@2514
   268
deba@2514
   269
      if (p != -1){
deba@2514
   270
	_data[p].parent = v;
deba@2514
   271
	_data[p].dmin -= min;
deba@2514
   272
      }
deba@2514
   273
      if (q!=-1){
deba@2514
   274
	_data[q].parent = v;
deba@2514
   275
	if (_tolerance.less(_data[q].dmin,_max_value)) {
deba@2514
   276
	  _data[q].dmin -= min;
deba@2514
   277
	}
deba@2514
   278
      }
deba@2514
   279
      _data[v].left = p;
deba@2514
   280
      _data[v].right = q;
deba@2514
   281
      if (_tolerance.less(min,_max_value)) {
deba@2514
   282
	_data[v].dcost = _data[v].dmin - min;
deba@2514
   283
      }
deba@2514
   284
      _data[v].dmin = min;
deba@2514
   285
    }
deba@2514
   286
deba@2514
   287
    void split(int &p, int v, int &q){
deba@2514
   288
      splay(v);
deba@2514
   289
      p = -1;
deba@2514
   290
      if (_data[v].left != -1){
deba@2514
   291
	p = _data[v].left;
deba@2514
   292
	_data[p].dmin += _data[v].dmin;
deba@2514
   293
	_data[p].parent = -1;
deba@2514
   294
	_data[v].left = -1;
deba@2514
   295
      }
deba@2514
   296
      q = -1;
deba@2514
   297
      if (_data[v].right != -1) {
deba@2514
   298
	q=_data[v].right;
deba@2514
   299
	if (_tolerance.less(_data[q].dmin, _max_value)) {
deba@2514
   300
	  _data[q].dmin += _data[v].dmin;
deba@2514
   301
	}
deba@2514
   302
	_data[q].parent = -1;
deba@2514
   303
	_data[v].right = -1;
deba@2514
   304
      } 
deba@2514
   305
      if (_tolerance.less(_data[v].dcost, _max_value)) {
deba@2514
   306
	_data[v].dmin += _data[v].dcost;
deba@2514
   307
	_data[v].dcost = 0;
deba@2514
   308
      } else {
deba@2514
   309
	_data[v].dmin = _data[v].dcost;
deba@2514
   310
      }
deba@2514
   311
    }
deba@2514
   312
 
deba@2514
   313
    int expose(int v) {
deba@2514
   314
      int p, q, r, w;
deba@2514
   315
      p = -1;
deba@2514
   316
      while (v != -1) {
deba@2514
   317
	w = _data[findPath(v)].successor;
deba@2514
   318
	split(q, v, r);
deba@2514
   319
	if (q != -1) {
deba@2514
   320
	  _data[q].successor = v;
deba@2514
   321
	}
deba@2514
   322
	join(p, v, r);
deba@2514
   323
	p = v;
deba@2514
   324
	v = w;
deba@2514
   325
      }
deba@2514
   326
      _data[p].successor = -1;
deba@2514
   327
      return p;
deba@2514
   328
    }
deba@2514
   329
deba@2514
   330
    void splay(int v) {
deba@2514
   331
      while (_data[v].parent != -1) {
deba@2514
   332
	if (v == _data[_data[v].parent].left) {
deba@2514
   333
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   334
	    zig(v);
deba@2514
   335
	  } else {
deba@2514
   336
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   337
	      zig(_data[v].parent);
deba@2514
   338
	      zig(v);
deba@2514
   339
	    } else {
deba@2514
   340
	      zig(v);
deba@2514
   341
	      zag(v);
deba@2514
   342
	    }
deba@2514
   343
	  }
deba@2514
   344
	} else {
deba@2514
   345
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   346
	    zag(v);
deba@2514
   347
	  } else {
deba@2514
   348
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   349
	      zag(v);
deba@2514
   350
	      zig(v);
deba@2514
   351
	    } else {
deba@2514
   352
	      zag(_data[v].parent);
deba@2514
   353
	      zag(v);
deba@2514
   354
	    }
deba@2514
   355
	  }
deba@2514
   356
	}
deba@2514
   357
      }
deba@2514
   358
    }
deba@2514
   359
deba@2514
   360
deba@2514
   361
    void zig(int v) {
deba@2514
   362
      Value min = _data[_data[v].parent].dmin;
deba@2514
   363
      int a = _data[v].parent;
deba@2514
   364
        
deba@2514
   365
      Value aa = _data[a].dcost;
deba@2514
   366
      if (_tolerance.less(aa, _max_value)) { 
deba@2519
   367
	aa += min;
deba@2514
   368
      }
deba@2514
   369
deba@2514
   370
deba@2514
   371
      int b = v;
deba@2514
   372
      Value ab = min + _data[b].dmin;
deba@2514
   373
      Value bb = _data[b].dcost;
deba@2514
   374
      if (_tolerance.less(bb, _max_value)) { 
deba@2519
   375
	bb += ab;
deba@2514
   376
      }
deba@2514
   377
deba@2514
   378
      int c = -1;
deba@2514
   379
      Value cc = _max_value;
deba@2514
   380
      if (_data[a].right != -1) {
deba@2514
   381
	c = _data[a].right;
deba@2514
   382
	cc = _data[c].dmin;
deba@2514
   383
	if (_tolerance.less(cc, _max_value)) {
deba@2519
   384
	  cc += min;
deba@2514
   385
	}
deba@2514
   386
      }
deba@2514
   387
deba@2514
   388
      int d = -1;
deba@2514
   389
      Value dd = _max_value;
deba@2514
   390
      if (_data[v].left != -1){
deba@2514
   391
	d = _data[v].left;
deba@2514
   392
	dd = ab + _data[d].dmin;
deba@2514
   393
      }
deba@2514
   394
deba@2514
   395
      int e = -1;
deba@2514
   396
      Value ee = _max_value;
deba@2514
   397
      if (_data[v].right != -1) {
deba@2514
   398
	e = _data[v].right;
deba@2514
   399
	ee = ab + _data[e].dmin;
deba@2514
   400
      }
deba@2514
   401
deba@2514
   402
      Value min2;
deba@2514
   403
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   404
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   405
	min2 = min;
deba@2514
   406
      } else {
deba@2514
   407
	if (_tolerance.less(aa, cc)) {
deba@2514
   408
	  if (_tolerance.less(aa, ee)) {
deba@2514
   409
	    min2 = aa;
deba@2514
   410
	  } else {
deba@2514
   411
	    min2 = ee;
deba@2514
   412
	  }
deba@2514
   413
	} else if (_tolerance.less(cc, ee)) {
deba@2514
   414
	  min2 = cc;
deba@2514
   415
	} else {
deba@2514
   416
	  min2 = ee;
deba@2514
   417
	}
deba@2514
   418
      }
deba@2514
   419
        
deba@2514
   420
      _data[a].dcost = aa;
deba@2514
   421
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   422
	_data[a].dcost -= min2;
deba@2514
   423
      }
deba@2514
   424
      _data[a].dmin = min2;
deba@2514
   425
      if (_tolerance.less(min2,_max_value)) { 
deba@2514
   426
	_data[a].dmin -= min; 
deba@2514
   427
      }
deba@2514
   428
      _data[a].size -= _data[b].size;
deba@2514
   429
      _data[b].dcost = bb;
deba@2514
   430
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   431
	_data[b].dcost -= min;
deba@2514
   432
      }
deba@2514
   433
      _data[b].dmin = min;
deba@2514
   434
      _data[b].size += _data[a].size;
deba@2514
   435
      if (c != -1) {
deba@2514
   436
	_data[c].dmin = cc;
deba@2514
   437
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   438
	  _data[c].dmin -= min2;
deba@2514
   439
	}
deba@2514
   440
      }
deba@2514
   441
      if (d != -1) {
deba@2514
   442
	_data[d].dmin = dd - min;
deba@2514
   443
	_data[a].size += _data[d].size;
deba@2514
   444
	_data[b].size -= _data[d].size;
deba@2514
   445
      }
deba@2514
   446
      if (e != -1) {
deba@2514
   447
	_data[e].dmin = ee - min2;
deba@2514
   448
      }
deba@2514
   449
        
deba@2514
   450
      int w = _data[v].parent;
deba@2514
   451
      _data[v].successor = _data[w].successor;
deba@2514
   452
      _data[w].successor = -1;
deba@2514
   453
      _data[v].parent = _data[w].parent;
deba@2514
   454
      _data[w].parent = v;
deba@2514
   455
      _data[w].left = _data[v].right;
deba@2514
   456
      _data[v].right = w;
deba@2514
   457
      if (_data[v].parent != -1){
deba@2514
   458
	if (_data[_data[v].parent].right == w) {
deba@2514
   459
	  _data[_data[v].parent].right = v;
deba@2514
   460
	} else {
deba@2514
   461
	  _data[_data[v].parent].left = v;
deba@2514
   462
	}
deba@2514
   463
      }
deba@2514
   464
      if (_data[w].left != -1){
deba@2514
   465
	_data[_data[w].left].parent = w;
deba@2514
   466
      }
deba@2514
   467
    }
deba@2514
   468
deba@2514
   469
deba@2514
   470
    void zag(int v) {
deba@2514
   471
deba@2514
   472
      Value min = _data[_data[v].parent].dmin;
deba@2514
   473
deba@2514
   474
      int a = _data[v].parent;
deba@2514
   475
      Value aa = _data[a].dcost;
deba@2514
   476
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   477
	aa += min;
deba@2514
   478
      }
deba@2514
   479
        
deba@2514
   480
      int b = v;
deba@2514
   481
      Value ab = min + _data[b].dmin;
deba@2514
   482
      Value bb = _data[b].dcost;
deba@2514
   483
      if (_tolerance.less(bb, _max_value)) {
deba@2514
   484
	bb += ab;
deba@2514
   485
      }
deba@2514
   486
deba@2514
   487
      int c = -1;
deba@2514
   488
      Value cc = _max_value;
deba@2514
   489
      if (_data[a].left != -1){
deba@2514
   490
	c = _data[a].left;
deba@2514
   491
	cc = min + _data[c].dmin;
deba@2514
   492
      }
deba@2514
   493
deba@2514
   494
      int d = -1;
deba@2514
   495
      Value dd = _max_value;
deba@2514
   496
      if (_data[v].right!=-1) {
deba@2514
   497
	d = _data[v].right;
deba@2514
   498
	dd = _data[d].dmin;
deba@2514
   499
	if (_tolerance.less(dd, _max_value)) {
deba@2514
   500
	  dd += ab;
deba@2514
   501
	}
deba@2514
   502
      }
deba@2514
   503
deba@2514
   504
      int e = -1;
deba@2514
   505
      Value ee = _max_value;
deba@2514
   506
      if (_data[v].left != -1){
deba@2514
   507
	e = _data[v].left;
deba@2514
   508
	ee = ab + _data[e].dmin;
deba@2514
   509
      }
deba@2514
   510
deba@2514
   511
      Value min2;
deba@2514
   512
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   513
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   514
	min2 = min;
deba@2514
   515
      } else {
deba@2514
   516
	if (_tolerance.less(aa, cc)) {
deba@2514
   517
	  if (_tolerance.less(aa, ee)) {
deba@2514
   518
	    min2 = aa;
deba@2514
   519
	  } else {
deba@2514
   520
	    min2 = ee;
deba@2514
   521
	  }
deba@2514
   522
	} else if (_tolerance.less(cc, ee)) {
deba@2514
   523
	  min2 = cc;
deba@2514
   524
	} else {
deba@2514
   525
	  min2 = ee;
deba@2514
   526
	}
deba@2514
   527
      }
deba@2514
   528
      _data[a].dcost = aa;
deba@2514
   529
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   530
	_data[a].dcost -= min2;
deba@2514
   531
      }
deba@2514
   532
      _data[a].dmin = min2;
deba@2514
   533
      if (_tolerance.less(min2, _max_value)) {
deba@2514
   534
	_data[a].dmin -= min;
deba@2514
   535
      }
deba@2514
   536
      _data[a].size -= _data[b].size;
deba@2514
   537
      _data[b].dcost = bb;
deba@2514
   538
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   539
	_data[b].dcost -= min;
deba@2514
   540
      }
deba@2514
   541
      _data[b].dmin = min;
deba@2514
   542
      _data[b].size += _data[a].size;
deba@2514
   543
      if (c != -1) {
deba@2514
   544
	_data[c].dmin = cc - min2;
deba@2514
   545
      }
deba@2514
   546
      if (d != -1) {
deba@2514
   547
	_data[d].dmin = dd;
deba@2514
   548
	_data[a].size += _data[d].size;
deba@2514
   549
	_data[b].size -= _data[d].size;
deba@2514
   550
	if (_tolerance.less(dd, _max_value)) {
deba@2514
   551
	  _data[d].dmin -= min;
deba@2514
   552
	}
deba@2514
   553
      }
deba@2514
   554
      if (e != -1) {
deba@2514
   555
	_data[e].dmin = ee - min2;
deba@2514
   556
      }
deba@2514
   557
        
deba@2514
   558
      int w = _data[v].parent;
deba@2514
   559
      _data[v].successor = _data[w].successor;
deba@2514
   560
      _data[w].successor = -1;
deba@2514
   561
      _data[v].parent = _data[w].parent;
deba@2514
   562
      _data[w].parent = v;
deba@2514
   563
      _data[w].right = _data[v].left;
deba@2514
   564
      _data[v].left = w;
deba@2514
   565
      if (_data[v].parent != -1){
deba@2514
   566
	if (_data[_data[v].parent].left == w) {
deba@2514
   567
	  _data[_data[v].parent].left = v;
deba@2514
   568
	} else {
deba@2514
   569
	  _data[_data[v].parent].right = v;
deba@2514
   570
	}
deba@2514
   571
      }
deba@2514
   572
      if (_data[w].right != -1){
deba@2514
   573
	_data[_data[w].right].parent = w;
deba@2514
   574
      }
deba@2514
   575
    }
deba@2514
   576
deba@2514
   577
  private:
deba@2514
   578
deba@2514
   579
    class ItemData {
deba@2514
   580
    public:
deba@2514
   581
      Item id;
deba@2514
   582
      int size;
deba@2514
   583
      int successor;
deba@2514
   584
      int parent;
deba@2514
   585
      int left;
deba@2514
   586
      int right;
deba@2514
   587
      Value dmin;
deba@2514
   588
      Value dcost;
deba@2514
   589
        
deba@2514
   590
    public:
deba@2514
   591
      ItemData(const Item &item)
deba@2514
   592
	: id(item), size(1), successor(), parent(-1), 
deba@2514
   593
	  left(-1), right(-1), dmin(0), dcost(0) {}
deba@2514
   594
    };
deba@2514
   595
     
deba@2514
   596
  };
deba@2514
   597
deba@2514
   598
  template <typename _Value, typename _ItemIntMap, typename _Tolerance>
deba@2514
   599
  class DynamicTree<_Value, _ItemIntMap, _Tolerance, false> {
deba@2514
   600
  public:
deba@2514
   601
    typedef _ItemIntMap ItemIntMap;
deba@2514
   602
    typedef typename ItemIntMap::Key Item;
deba@2514
   603
    typedef _Value Value;
deba@2514
   604
    typedef _Tolerance Tolerance;
deba@2514
   605
deba@2514
   606
  private:
deba@2514
   607
  
deba@2514
   608
    class ItemData;
deba@2514
   609
deba@2514
   610
    std::vector<ItemData> _data;
deba@2514
   611
    ItemIntMap &_iim;
deba@2514
   612
    Value _max_value;
deba@2514
   613
    Tolerance _tolerance;
deba@2514
   614
deba@2514
   615
  public:
deba@2514
   616
    DynamicTree(ItemIntMap &iim, const Tolerance& tolerance = Tolerance())
deba@2514
   617
      : _iim(iim), _max_value(std::numeric_limits<Value>::max()), 
deba@2514
   618
	_tolerance(tolerance) {}
deba@2514
   619
  
deba@2514
   620
    ~DynamicTree() {}
deba@2514
   621
deba@2514
   622
    void clear() {
deba@2514
   623
      _data.clear();
deba@2514
   624
    }
deba@2514
   625
deba@2514
   626
    void tolerance(const Tolerance& tolerance) const {
deba@2514
   627
      _tolerance = tolerance;
deba@2514
   628
      return *this;
deba@2514
   629
    } 
deba@2514
   630
  
deba@2514
   631
    const Tolerance& tolerance() const {
deba@2514
   632
      return tolerance;
deba@2514
   633
    } 
deba@2514
   634
  
deba@2514
   635
    void makeTree(const Item &item) {
deba@2514
   636
      _data[makePath(item)].successor = -1;
deba@2514
   637
    }
deba@2514
   638
    
deba@2514
   639
    Item findRoot(const Item &item) {
deba@2514
   640
      return _data[findTail(expose(_iim[item]))].id;
deba@2514
   641
    }
deba@2514
   642
    
deba@2514
   643
    Item findCost(const Item &item, Value& d){
deba@2514
   644
      return _data[findPathCost(expose(_iim[item]),d)].id;
deba@2514
   645
    }
deba@2514
   646
    
deba@2514
   647
    void addCost(const Item &item, Value x){
deba@2514
   648
      addPathCost(expose(_iim[item]), x);
deba@2514
   649
    }
deba@2514
   650
    
deba@2514
   651
    void link(const Item &item1, const Item &item2){
deba@2514
   652
      int v = _iim[item1];
deba@2514
   653
      int w = _iim[item2];
deba@2514
   654
      int p = expose(w);
deba@2514
   655
      join(-1, expose(v), p);
deba@2514
   656
      _data[v].successor = -1;
deba@2514
   657
    }    
deba@2514
   658
    
deba@2514
   659
    void cut(const Item &item) {
deba@2514
   660
      int v = _iim[item];
deba@2514
   661
      int p, q;
deba@2514
   662
      expose(v);
deba@2514
   663
      split(p, v, q);
deba@2514
   664
      if (p != -1) {
deba@2514
   665
	_data[p].successor = v;
deba@2514
   666
      }
deba@2514
   667
      if (q != -1) {
deba@2514
   668
	_data[q].successor = _data[v].successor;
deba@2514
   669
      }
deba@2514
   670
      _data[v].successor = -1;
deba@2514
   671
    }
deba@2514
   672
deba@2514
   673
    Item parent(const Item &item){
deba@2514
   674
      return _data[_iim[item].p].id;
deba@2514
   675
    }
deba@2514
   676
deba@2514
   677
    Value maxValue() const {
deba@2514
   678
      return _max_value;
deba@2514
   679
    }
deba@2514
   680
    
deba@2514
   681
  private:
deba@2514
   682
deba@2514
   683
    int makePath(const Item &item) {
deba@2514
   684
      _iim.set(item, _data.size());
deba@2514
   685
      ItemData v(item);
deba@2514
   686
      _data.push_back(v);
deba@2514
   687
      return _iim[item];
deba@2514
   688
    }
deba@2514
   689
deba@2519
   690
    int findPath(int v) {
deba@2514
   691
      splay(v);
deba@2514
   692
      return v;
deba@2514
   693
    }
deba@2514
   694
    
deba@2519
   695
    int findPathCost(int p, Value &d) {
deba@2514
   696
      while ((_data[p].right != -1 && 
deba@2514
   697
	      !_tolerance.less(0, _data[_data[p].right].dmin)) || 
deba@2514
   698
	     (_data[p].left != -1 && _tolerance.less(0, _data[p].dcost))) {
deba@2514
   699
	if (_data[p].right != -1 && 
deba@2514
   700
	    !_tolerance.less(0, _data[_data[p].right].dmin)) {
deba@2514
   701
	  p = _data[p].right;
deba@2514
   702
	} else if (_data[p].left != -1 && 
deba@2514
   703
		   !_tolerance.less(0, _data[_data[p].left].dmin)){
deba@2514
   704
	  p = _data[p].left;
deba@2514
   705
	}
deba@2514
   706
      }
deba@2514
   707
      splay(p);
deba@2514
   708
      d = _data[p].dmin;
deba@2514
   709
      return p; 
deba@2514
   710
    }
deba@2514
   711
deba@2519
   712
    int findTail(int p) {
deba@2514
   713
      while (_data[p].right != -1) {
deba@2514
   714
	p = _data[p].right;
deba@2514
   715
      }
deba@2514
   716
      splay(p);
deba@2514
   717
      return p;
deba@2514
   718
    }
deba@2514
   719
    
deba@2519
   720
    void addPathCost(int p, Value x) {
deba@2514
   721
      if (!_tolerance.less(x, _max_value)) {
deba@2514
   722
	_data[p].dmin = x;_data[p].dcost = x;
deba@2514
   723
      } else if (!_tolerance.less(-x, _max_value)) {
deba@2514
   724
	_data[p].dmin = 0;
deba@2514
   725
	_data[p].dcost = 0;
deba@2514
   726
      } else {
deba@2514
   727
	_data[p].dmin += x;
deba@2514
   728
      }
deba@2514
   729
    }
deba@2514
   730
deba@2514
   731
    void join(int p, int v, int q) {
deba@2514
   732
      Value min = _max_value;
deba@2514
   733
      Value pmin = _max_value;
deba@2514
   734
      Value vmin = _data[v].dmin;
deba@2514
   735
      Value qmin = _max_value;
deba@2514
   736
      if (p != -1){
deba@2514
   737
	pmin = _data[p].dmin;
deba@2514
   738
      }
deba@2514
   739
      if (q != -1){
deba@2514
   740
	qmin = _data[q].dmin;
deba@2514
   741
      }
deba@2514
   742
        
deba@2514
   743
      if (_tolerance.less(vmin, qmin)) {
deba@2514
   744
	if (_tolerance.less(vmin,pmin)) {
deba@2514
   745
	  min = vmin;
deba@2514
   746
	} else {
deba@2514
   747
	  min = pmin;
deba@2514
   748
	}
deba@2514
   749
      } else if (_tolerance.less(qmin,pmin)) {
deba@2514
   750
	min = qmin;
deba@2514
   751
      } else {
deba@2514
   752
	min = pmin;
deba@2514
   753
      }
deba@2514
   754
deba@2514
   755
      if (p != -1){
deba@2514
   756
	_data[p].parent = v;
deba@2514
   757
	_data[p].dmin -= min;
deba@2514
   758
      }
deba@2519
   759
      if (q != -1){
deba@2514
   760
	_data[q].parent = v;
deba@2514
   761
	if (_tolerance.less(_data[q].dmin,_max_value)) {
deba@2514
   762
	  _data[q].dmin -= min;
deba@2514
   763
	}
deba@2514
   764
      }
deba@2514
   765
      _data[v].left = p;
deba@2514
   766
      _data[v].right = q;
deba@2519
   767
      if (_tolerance.less(min, _max_value)) {
deba@2514
   768
	_data[v].dcost = _data[v].dmin - min;
deba@2514
   769
      }
deba@2514
   770
      _data[v].dmin = min;
deba@2514
   771
    }
deba@2514
   772
deba@2514
   773
    void split(int &p, int v, int &q){
deba@2514
   774
      splay(v);
deba@2514
   775
      p = -1;
deba@2514
   776
      if (_data[v].left != -1){
deba@2514
   777
	p = _data[v].left;
deba@2514
   778
	_data[p].dmin += _data[v].dmin;
deba@2514
   779
	_data[p].parent = -1;
deba@2514
   780
	_data[v].left = -1;
deba@2514
   781
      }
deba@2514
   782
      q = -1;
deba@2514
   783
      if (_data[v].right != -1) {
deba@2514
   784
	q=_data[v].right;
deba@2514
   785
	if (_tolerance.less(_data[q].dmin, _max_value)) {
deba@2514
   786
	  _data[q].dmin += _data[v].dmin;
deba@2514
   787
	}
deba@2514
   788
	_data[q].parent = -1;
deba@2514
   789
	_data[v].right = -1;
deba@2514
   790
      } 
deba@2514
   791
      if (_tolerance.less(_data[v].dcost, _max_value)) {
deba@2514
   792
	_data[v].dmin += _data[v].dcost;
deba@2514
   793
	_data[v].dcost = 0;
deba@2514
   794
      } else {
deba@2514
   795
	_data[v].dmin = _data[v].dcost;
deba@2514
   796
      }
deba@2514
   797
    }
deba@2514
   798
 
deba@2514
   799
    int expose(int v) {
deba@2514
   800
      int p, q, r, w;
deba@2514
   801
      p = -1;
deba@2514
   802
      while (v != -1) {
deba@2514
   803
	w = _data[findPath(v)].successor;
deba@2514
   804
	split(q, v, r);
deba@2514
   805
	if (q != -1) {
deba@2514
   806
	  _data[q].successor = v;
deba@2514
   807
	}
deba@2514
   808
	join(p, v, r);
deba@2514
   809
	p = v;
deba@2514
   810
	v = w;
deba@2514
   811
      }
deba@2514
   812
      _data[p].successor = -1;
deba@2514
   813
      return p;
deba@2514
   814
    }
deba@2514
   815
deba@2514
   816
    void splay(int v) {
deba@2514
   817
      while (_data[v].parent != -1) {
deba@2514
   818
	if (v == _data[_data[v].parent].left) {
deba@2514
   819
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   820
	    zig(v);
deba@2514
   821
	  } else {
deba@2514
   822
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   823
	      zig(_data[v].parent);
deba@2514
   824
	      zig(v);
deba@2514
   825
	    } else {
deba@2514
   826
	      zig(v);
deba@2514
   827
	      zag(v);
deba@2514
   828
	    }
deba@2514
   829
	  }
deba@2514
   830
	} else {
deba@2514
   831
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   832
	    zag(v);
deba@2514
   833
	  } else {
deba@2514
   834
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   835
	      zag(v);
deba@2514
   836
	      zig(v);
deba@2514
   837
	    } else {
deba@2514
   838
	      zag(_data[v].parent);
deba@2514
   839
	      zag(v);
deba@2514
   840
	    }
deba@2514
   841
	  }
deba@2514
   842
	}
deba@2514
   843
      }
deba@2514
   844
    }
deba@2514
   845
deba@2514
   846
deba@2514
   847
    void zig(int v) {
deba@2514
   848
      Value min = _data[_data[v].parent].dmin;
deba@2514
   849
      int a = _data[v].parent;
deba@2514
   850
        
deba@2514
   851
      Value aa = _data[a].dcost;
deba@2514
   852
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   853
	aa+= min;
deba@2514
   854
      }
deba@2514
   855
deba@2514
   856
deba@2514
   857
      int b = v;
deba@2514
   858
      Value ab = min + _data[b].dmin;
deba@2514
   859
      Value bb = _data[b].dcost;
deba@2514
   860
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   861
	bb+= ab;
deba@2514
   862
      }
deba@2514
   863
deba@2514
   864
      int c = -1;
deba@2514
   865
      Value cc = _max_value;
deba@2514
   866
      if (_data[a].right != -1) {
deba@2514
   867
	c = _data[a].right;
deba@2514
   868
	cc = _data[c].dmin;
deba@2514
   869
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   870
	  cc+=min;
deba@2514
   871
	}
deba@2514
   872
      }
deba@2514
   873
deba@2514
   874
      int d = -1;
deba@2514
   875
      Value dd = _max_value;
deba@2514
   876
      if (_data[v].left != -1){
deba@2514
   877
	d = _data[v].left;
deba@2514
   878
	dd = ab + _data[d].dmin;
deba@2514
   879
      }
deba@2514
   880
deba@2514
   881
      int e = -1;
deba@2514
   882
      Value ee = _max_value;
deba@2514
   883
      if (_data[v].right != -1) {
deba@2514
   884
	e = _data[v].right;
deba@2514
   885
	ee = ab + _data[e].dmin;
deba@2514
   886
      }
deba@2514
   887
deba@2514
   888
      Value min2;
deba@2514
   889
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   890
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   891
	min2 = min;
deba@2514
   892
      } else {
deba@2514
   893
	if (_tolerance.less(aa, cc)) {
deba@2514
   894
	  if (_tolerance.less(aa, ee)) {
deba@2514
   895
	    min2 = aa;
deba@2514
   896
	  } else {
deba@2514
   897
	    min2 = ee;
deba@2514
   898
	  }
deba@2514
   899
	} else if (_tolerance.less(cc, ee)) {
deba@2514
   900
	  min2 = cc;
deba@2514
   901
	} else {
deba@2514
   902
	  min2 = ee;
deba@2514
   903
	}
deba@2514
   904
      }
deba@2514
   905
        
deba@2514
   906
      _data[a].dcost = aa;
deba@2514
   907
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   908
	_data[a].dcost -= min2;
deba@2514
   909
      }
deba@2514
   910
      _data[a].dmin = min2;
deba@2514
   911
      if (_tolerance.less(min2,_max_value)) { 
deba@2514
   912
	_data[a].dmin -= min; 
deba@2514
   913
      }
deba@2514
   914
      _data[b].dcost = bb;
deba@2514
   915
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   916
	_data[b].dcost -= min;
deba@2514
   917
      }
deba@2514
   918
      _data[b].dmin = min;
deba@2514
   919
      if (c != -1) {
deba@2514
   920
	_data[c].dmin = cc;
deba@2514
   921
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   922
	  _data[c].dmin -= min2;
deba@2514
   923
	}
deba@2514
   924
      }
deba@2514
   925
      if (d != -1) {
deba@2514
   926
	_data[d].dmin = dd - min;
deba@2514
   927
      }
deba@2514
   928
      if (e != -1) {
deba@2514
   929
	_data[e].dmin = ee - min2;
deba@2514
   930
      }
deba@2514
   931
        
deba@2514
   932
      int w = _data[v].parent;
deba@2514
   933
      _data[v].successor = _data[w].successor;
deba@2514
   934
      _data[w].successor = -1;
deba@2514
   935
      _data[v].parent = _data[w].parent;
deba@2514
   936
      _data[w].parent = v;
deba@2514
   937
      _data[w].left = _data[v].right;
deba@2514
   938
      _data[v].right = w;
deba@2514
   939
      if (_data[v].parent != -1){
deba@2514
   940
	if (_data[_data[v].parent].right == w) {
deba@2514
   941
	  _data[_data[v].parent].right = v;
deba@2514
   942
	} else {
deba@2514
   943
	  _data[_data[v].parent].left = v;
deba@2514
   944
	}
deba@2514
   945
      }
deba@2514
   946
      if (_data[w].left != -1){
deba@2514
   947
	_data[_data[w].left].parent = w;
deba@2514
   948
      }
deba@2514
   949
    }
deba@2514
   950
deba@2514
   951
deba@2514
   952
    void zag(int v) {
deba@2514
   953
deba@2514
   954
      Value min = _data[_data[v].parent].dmin;
deba@2514
   955
deba@2514
   956
      int a = _data[v].parent;
deba@2514
   957
      Value aa = _data[a].dcost;
deba@2514
   958
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   959
	aa += min;
deba@2514
   960
      }
deba@2514
   961
        
deba@2514
   962
      int b = v;
deba@2514
   963
      Value ab = min + _data[b].dmin;
deba@2514
   964
      Value bb = _data[b].dcost;
deba@2514
   965
      if (_tolerance.less(bb, _max_value)) {
deba@2514
   966
	bb += ab;
deba@2514
   967
      }
deba@2514
   968
deba@2514
   969
      int c = -1;
deba@2514
   970
      Value cc = _max_value;
deba@2514
   971
      if (_data[a].left != -1){
deba@2514
   972
	c = _data[a].left;
deba@2514
   973
	cc = min + _data[c].dmin;
deba@2514
   974
      }
deba@2514
   975
deba@2514
   976
      int d = -1;
deba@2514
   977
      Value dd = _max_value;
deba@2514
   978
      if (_data[v].right!=-1) {
deba@2514
   979
	d = _data[v].right;
deba@2514
   980
	dd = _data[d].dmin;
deba@2514
   981
	if (_tolerance.less(dd, _max_value)) {
deba@2514
   982
	  dd += ab;
deba@2514
   983
	}
deba@2514
   984
      }
deba@2514
   985
deba@2514
   986
      int e = -1;
deba@2514
   987
      Value ee = _max_value;
deba@2514
   988
      if (_data[v].left != -1){
deba@2514
   989
	e = _data[v].left;
deba@2514
   990
	ee = ab + _data[e].dmin;
deba@2514
   991
      }
deba@2514
   992
deba@2514
   993
      Value min2;
deba@2514
   994
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   995
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   996
	min2 = min;
deba@2514
   997
      } else {
deba@2514
   998
	if (_tolerance.less(aa, cc)) {
deba@2514
   999
	  if (_tolerance.less(aa, ee)) {
deba@2514
  1000
	    min2 = aa;
deba@2514
  1001
	  } else {
deba@2514
  1002
	    min2 = ee;
deba@2514
  1003
	  }
deba@2514
  1004
	} else if (_tolerance.less(cc, ee)) {
deba@2514
  1005
	  min2 = cc;
deba@2514
  1006
	} else {
deba@2514
  1007
	  min2 = ee;
deba@2514
  1008
	}
deba@2514
  1009
      }
deba@2514
  1010
      _data[a].dcost = aa;
deba@2514
  1011
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
  1012
	_data[a].dcost -= min2;
deba@2514
  1013
      }
deba@2514
  1014
      _data[a].dmin = min2;
deba@2514
  1015
      if (_tolerance.less(min2, _max_value)) {
deba@2514
  1016
	_data[a].dmin -= min;
deba@2514
  1017
      }
deba@2514
  1018
      _data[b].dcost = bb;
deba@2514
  1019
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
  1020
	_data[b].dcost -= min;
deba@2514
  1021
      }
deba@2514
  1022
      _data[b].dmin = min;
deba@2514
  1023
      if (c != -1) {
deba@2514
  1024
	_data[c].dmin = cc - min2;
deba@2514
  1025
      }
deba@2514
  1026
      if (d != -1) {
deba@2514
  1027
	_data[d].dmin = dd;
deba@2514
  1028
	if (_tolerance.less(dd, _max_value)) {
deba@2514
  1029
	  _data[d].dmin -= min;
deba@2514
  1030
	}
deba@2514
  1031
      }
deba@2514
  1032
      if (e != -1) {
deba@2514
  1033
	_data[e].dmin = ee - min2;
deba@2514
  1034
      }
deba@2514
  1035
        
deba@2514
  1036
      int w = _data[v].parent;
deba@2514
  1037
      _data[v].successor = _data[w].successor;
deba@2514
  1038
      _data[w].successor = -1;
deba@2514
  1039
      _data[v].parent = _data[w].parent;
deba@2514
  1040
      _data[w].parent = v;
deba@2514
  1041
      _data[w].right = _data[v].left;
deba@2514
  1042
      _data[v].left = w;
deba@2514
  1043
      if (_data[v].parent != -1){
deba@2514
  1044
	if (_data[_data[v].parent].left == w) {
deba@2514
  1045
	  _data[_data[v].parent].left = v;
deba@2514
  1046
	} else {
deba@2514
  1047
	  _data[_data[v].parent].right = v;
deba@2514
  1048
	}
deba@2514
  1049
      }
deba@2514
  1050
      if (_data[w].right != -1){
deba@2514
  1051
	_data[_data[w].right].parent = w;
deba@2514
  1052
      }
deba@2514
  1053
    }
deba@2514
  1054
deba@2514
  1055
  private:
deba@2514
  1056
deba@2514
  1057
    class ItemData {
deba@2514
  1058
    public:
deba@2514
  1059
      Item id;
deba@2514
  1060
      int successor;
deba@2514
  1061
      int parent;
deba@2514
  1062
      int left;
deba@2514
  1063
      int right;
deba@2514
  1064
      Value dmin;
deba@2514
  1065
      Value dcost;
deba@2514
  1066
        
deba@2514
  1067
    public:
deba@2514
  1068
      ItemData(const Item &item)
deba@2514
  1069
	: id(item), successor(), parent(-1), 
deba@2514
  1070
	  left(-1), right(-1), dmin(0), dcost(0) {}
deba@2514
  1071
    };
deba@2514
  1072
     
deba@2514
  1073
  };
deba@2514
  1074
deba@2514
  1075
}
deba@2514
  1076
deba@2514
  1077
#endif