lemon/dynamic_tree.h
author deba
Sat, 17 Nov 2007 20:58:11 +0000
changeset 2514 57143c09dc20
child 2519 a7376f7ed899
permissions -rw-r--r--
Redesign the maximum flow algorithms

Redesigned interface
Preflow changed to use elevator
Edmonds-Karp does not use the ResGraphAdaptor
Goldberg-Tarjan algorithm (Preflow with Dynamic Trees)
Dinitz-Sleator-Tarjan (Blocking flow with Dynamic Tree)
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@2514
   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@2514
   203
    int findPath(int v){
deba@2514
   204
      splay(v);
deba@2514
   205
      return v;
deba@2514
   206
    }
deba@2514
   207
    
deba@2514
   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@2514
   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@2514
   233
    void addPathCost(int p, Value x){
deba@2514
   234
      if (!_tolerance.less(x, _max_value)) {
deba@2514
   235
	_data[p].dmin = x;_data[p].dcost = x;
deba@2514
   236
      } else if (!_tolerance.less(-x, _max_value)) {
deba@2514
   237
	_data[p].dmin = 0;
deba@2514
   238
	_data[p].dcost = 0;
deba@2514
   239
      } else {
deba@2514
   240
	_data[p].dmin += x;
deba@2514
   241
      }
deba@2514
   242
    }
deba@2514
   243
deba@2514
   244
    void join(int p, int v, int q) {
deba@2514
   245
      Value min = _max_value;
deba@2514
   246
      Value pmin = _max_value;
deba@2514
   247
      Value vmin = _data[v].dmin;
deba@2514
   248
      Value qmin = _max_value;
deba@2514
   249
      if (p != -1){
deba@2514
   250
	pmin = _data[p].dmin;
deba@2514
   251
      }
deba@2514
   252
      if (q != -1){
deba@2514
   253
	qmin = _data[q].dmin;
deba@2514
   254
      }
deba@2514
   255
        
deba@2514
   256
      if (_tolerance.less(vmin, qmin)) {
deba@2514
   257
	if (_tolerance.less(vmin,pmin)) {
deba@2514
   258
	  min = vmin;
deba@2514
   259
	} else {
deba@2514
   260
	  min = pmin;
deba@2514
   261
	}
deba@2514
   262
      } else if (_tolerance.less(qmin,pmin)) {
deba@2514
   263
	min = qmin;
deba@2514
   264
      } else {
deba@2514
   265
	min = pmin;
deba@2514
   266
      }
deba@2514
   267
deba@2514
   268
      if (p != -1){
deba@2514
   269
	_data[p].parent = v;
deba@2514
   270
	_data[p].dmin -= min;
deba@2514
   271
      }
deba@2514
   272
      if (q!=-1){
deba@2514
   273
	_data[q].parent = v;
deba@2514
   274
	if (_tolerance.less(_data[q].dmin,_max_value)) {
deba@2514
   275
	  _data[q].dmin -= min;
deba@2514
   276
	}
deba@2514
   277
      }
deba@2514
   278
      _data[v].left = p;
deba@2514
   279
      _data[v].right = q;
deba@2514
   280
      if (_tolerance.less(min,_max_value)) {
deba@2514
   281
	_data[v].dcost = _data[v].dmin - min;
deba@2514
   282
      }
deba@2514
   283
      _data[v].dmin = min;
deba@2514
   284
    }
deba@2514
   285
deba@2514
   286
    void split(int &p, int v, int &q){
deba@2514
   287
      splay(v);
deba@2514
   288
      p = -1;
deba@2514
   289
      if (_data[v].left != -1){
deba@2514
   290
	p = _data[v].left;
deba@2514
   291
	_data[p].dmin += _data[v].dmin;
deba@2514
   292
	_data[p].parent = -1;
deba@2514
   293
	_data[v].left = -1;
deba@2514
   294
      }
deba@2514
   295
      q = -1;
deba@2514
   296
      if (_data[v].right != -1) {
deba@2514
   297
	q=_data[v].right;
deba@2514
   298
	if (_tolerance.less(_data[q].dmin, _max_value)) {
deba@2514
   299
	  _data[q].dmin += _data[v].dmin;
deba@2514
   300
	}
deba@2514
   301
	_data[q].parent = -1;
deba@2514
   302
	_data[v].right = -1;
deba@2514
   303
      } 
deba@2514
   304
      if (_tolerance.less(_data[v].dcost, _max_value)) {
deba@2514
   305
	_data[v].dmin += _data[v].dcost;
deba@2514
   306
	_data[v].dcost = 0;
deba@2514
   307
      } else {
deba@2514
   308
	_data[v].dmin = _data[v].dcost;
deba@2514
   309
      }
deba@2514
   310
    }
deba@2514
   311
 
deba@2514
   312
    int expose(int v) {
deba@2514
   313
      int p, q, r, w;
deba@2514
   314
      p = -1;
deba@2514
   315
      while (v != -1) {
deba@2514
   316
	w = _data[findPath(v)].successor;
deba@2514
   317
	split(q, v, r);
deba@2514
   318
	if (q != -1) {
deba@2514
   319
	  _data[q].successor = v;
deba@2514
   320
	}
deba@2514
   321
	join(p, v, r);
deba@2514
   322
	p = v;
deba@2514
   323
	v = w;
deba@2514
   324
      }
deba@2514
   325
      _data[p].successor = -1;
deba@2514
   326
      return p;
deba@2514
   327
    }
deba@2514
   328
deba@2514
   329
    void splay(int v) {
deba@2514
   330
      while (_data[v].parent != -1) {
deba@2514
   331
	if (v == _data[_data[v].parent].left) {
deba@2514
   332
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   333
	    zig(v);
deba@2514
   334
	  } else {
deba@2514
   335
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   336
	      zig(_data[v].parent);
deba@2514
   337
	      zig(v);
deba@2514
   338
	    } else {
deba@2514
   339
	      zig(v);
deba@2514
   340
	      zag(v);
deba@2514
   341
	    }
deba@2514
   342
	  }
deba@2514
   343
	} else {
deba@2514
   344
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   345
	    zag(v);
deba@2514
   346
	  } else {
deba@2514
   347
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   348
	      zag(v);
deba@2514
   349
	      zig(v);
deba@2514
   350
	    } else {
deba@2514
   351
	      zag(_data[v].parent);
deba@2514
   352
	      zag(v);
deba@2514
   353
	    }
deba@2514
   354
	  }
deba@2514
   355
	}
deba@2514
   356
      }
deba@2514
   357
    }
deba@2514
   358
deba@2514
   359
deba@2514
   360
    void zig(int v) {
deba@2514
   361
      Value min = _data[_data[v].parent].dmin;
deba@2514
   362
      int a = _data[v].parent;
deba@2514
   363
        
deba@2514
   364
      Value aa = _data[a].dcost;
deba@2514
   365
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   366
	aa+= min;
deba@2514
   367
      }
deba@2514
   368
deba@2514
   369
deba@2514
   370
      int b = v;
deba@2514
   371
      Value ab = min + _data[b].dmin;
deba@2514
   372
      Value bb = _data[b].dcost;
deba@2514
   373
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   374
	bb+= ab;
deba@2514
   375
      }
deba@2514
   376
deba@2514
   377
      int c = -1;
deba@2514
   378
      Value cc = _max_value;
deba@2514
   379
      if (_data[a].right != -1) {
deba@2514
   380
	c = _data[a].right;
deba@2514
   381
	cc = _data[c].dmin;
deba@2514
   382
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   383
	  cc+=min;
deba@2514
   384
	}
deba@2514
   385
      }
deba@2514
   386
deba@2514
   387
      int d = -1;
deba@2514
   388
      Value dd = _max_value;
deba@2514
   389
      if (_data[v].left != -1){
deba@2514
   390
	d = _data[v].left;
deba@2514
   391
	dd = ab + _data[d].dmin;
deba@2514
   392
      }
deba@2514
   393
deba@2514
   394
      int e = -1;
deba@2514
   395
      Value ee = _max_value;
deba@2514
   396
      if (_data[v].right != -1) {
deba@2514
   397
	e = _data[v].right;
deba@2514
   398
	ee = ab + _data[e].dmin;
deba@2514
   399
      }
deba@2514
   400
deba@2514
   401
      Value min2;
deba@2514
   402
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   403
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   404
	min2 = min;
deba@2514
   405
      } else {
deba@2514
   406
	if (_tolerance.less(aa, cc)) {
deba@2514
   407
	  if (_tolerance.less(aa, ee)) {
deba@2514
   408
	    min2 = aa;
deba@2514
   409
	  } else {
deba@2514
   410
	    min2 = ee;
deba@2514
   411
	  }
deba@2514
   412
	} else if (_tolerance.less(cc, ee)) {
deba@2514
   413
	  min2 = cc;
deba@2514
   414
	} else {
deba@2514
   415
	  min2 = ee;
deba@2514
   416
	}
deba@2514
   417
      }
deba@2514
   418
        
deba@2514
   419
      _data[a].dcost = aa;
deba@2514
   420
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   421
	_data[a].dcost -= min2;
deba@2514
   422
      }
deba@2514
   423
      _data[a].dmin = min2;
deba@2514
   424
      if (_tolerance.less(min2,_max_value)) { 
deba@2514
   425
	_data[a].dmin -= min; 
deba@2514
   426
      }
deba@2514
   427
      _data[a].size -= _data[b].size;
deba@2514
   428
      _data[b].dcost = bb;
deba@2514
   429
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   430
	_data[b].dcost -= min;
deba@2514
   431
      }
deba@2514
   432
      _data[b].dmin = min;
deba@2514
   433
      _data[b].size += _data[a].size;
deba@2514
   434
      if (c != -1) {
deba@2514
   435
	_data[c].dmin = cc;
deba@2514
   436
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   437
	  _data[c].dmin -= min2;
deba@2514
   438
	}
deba@2514
   439
      }
deba@2514
   440
      if (d != -1) {
deba@2514
   441
	_data[d].dmin = dd - min;
deba@2514
   442
	_data[a].size += _data[d].size;
deba@2514
   443
	_data[b].size -= _data[d].size;
deba@2514
   444
      }
deba@2514
   445
      if (e != -1) {
deba@2514
   446
	_data[e].dmin = ee - min2;
deba@2514
   447
      }
deba@2514
   448
        
deba@2514
   449
      int w = _data[v].parent;
deba@2514
   450
      _data[v].successor = _data[w].successor;
deba@2514
   451
      _data[w].successor = -1;
deba@2514
   452
      _data[v].parent = _data[w].parent;
deba@2514
   453
      _data[w].parent = v;
deba@2514
   454
      _data[w].left = _data[v].right;
deba@2514
   455
      _data[v].right = w;
deba@2514
   456
      if (_data[v].parent != -1){
deba@2514
   457
	if (_data[_data[v].parent].right == w) {
deba@2514
   458
	  _data[_data[v].parent].right = v;
deba@2514
   459
	} else {
deba@2514
   460
	  _data[_data[v].parent].left = v;
deba@2514
   461
	}
deba@2514
   462
      }
deba@2514
   463
      if (_data[w].left != -1){
deba@2514
   464
	_data[_data[w].left].parent = w;
deba@2514
   465
      }
deba@2514
   466
    }
deba@2514
   467
deba@2514
   468
deba@2514
   469
    void zag(int v) {
deba@2514
   470
deba@2514
   471
      Value min = _data[_data[v].parent].dmin;
deba@2514
   472
deba@2514
   473
      int a = _data[v].parent;
deba@2514
   474
      Value aa = _data[a].dcost;
deba@2514
   475
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   476
	aa += min;
deba@2514
   477
      }
deba@2514
   478
        
deba@2514
   479
      int b = v;
deba@2514
   480
      Value ab = min + _data[b].dmin;
deba@2514
   481
      Value bb = _data[b].dcost;
deba@2514
   482
      if (_tolerance.less(bb, _max_value)) {
deba@2514
   483
	bb += ab;
deba@2514
   484
      }
deba@2514
   485
deba@2514
   486
      int c = -1;
deba@2514
   487
      Value cc = _max_value;
deba@2514
   488
      if (_data[a].left != -1){
deba@2514
   489
	c = _data[a].left;
deba@2514
   490
	cc = min + _data[c].dmin;
deba@2514
   491
      }
deba@2514
   492
deba@2514
   493
      int d = -1;
deba@2514
   494
      Value dd = _max_value;
deba@2514
   495
      if (_data[v].right!=-1) {
deba@2514
   496
	d = _data[v].right;
deba@2514
   497
	dd = _data[d].dmin;
deba@2514
   498
	if (_tolerance.less(dd, _max_value)) {
deba@2514
   499
	  dd += ab;
deba@2514
   500
	}
deba@2514
   501
      }
deba@2514
   502
deba@2514
   503
      int e = -1;
deba@2514
   504
      Value ee = _max_value;
deba@2514
   505
      if (_data[v].left != -1){
deba@2514
   506
	e = _data[v].left;
deba@2514
   507
	ee = ab + _data[e].dmin;
deba@2514
   508
      }
deba@2514
   509
deba@2514
   510
      Value min2;
deba@2514
   511
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   512
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   513
	min2 = min;
deba@2514
   514
      } else {
deba@2514
   515
	if (_tolerance.less(aa, cc)) {
deba@2514
   516
	  if (_tolerance.less(aa, ee)) {
deba@2514
   517
	    min2 = aa;
deba@2514
   518
	  } else {
deba@2514
   519
	    min2 = ee;
deba@2514
   520
	  }
deba@2514
   521
	} else if (_tolerance.less(cc, ee)) {
deba@2514
   522
	  min2 = cc;
deba@2514
   523
	} else {
deba@2514
   524
	  min2 = ee;
deba@2514
   525
	}
deba@2514
   526
      }
deba@2514
   527
      _data[a].dcost = aa;
deba@2514
   528
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   529
	_data[a].dcost -= min2;
deba@2514
   530
      }
deba@2514
   531
      _data[a].dmin = min2;
deba@2514
   532
      if (_tolerance.less(min2, _max_value)) {
deba@2514
   533
	_data[a].dmin -= min;
deba@2514
   534
      }
deba@2514
   535
      _data[a].size -= _data[b].size;
deba@2514
   536
      _data[b].dcost = bb;
deba@2514
   537
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   538
	_data[b].dcost -= min;
deba@2514
   539
      }
deba@2514
   540
      _data[b].dmin = min;
deba@2514
   541
      _data[b].size += _data[a].size;
deba@2514
   542
      if (c != -1) {
deba@2514
   543
	_data[c].dmin = cc - min2;
deba@2514
   544
      }
deba@2514
   545
      if (d != -1) {
deba@2514
   546
	_data[d].dmin = dd;
deba@2514
   547
	_data[a].size += _data[d].size;
deba@2514
   548
	_data[b].size -= _data[d].size;
deba@2514
   549
	if (_tolerance.less(dd, _max_value)) {
deba@2514
   550
	  _data[d].dmin -= min;
deba@2514
   551
	}
deba@2514
   552
      }
deba@2514
   553
      if (e != -1) {
deba@2514
   554
	_data[e].dmin = ee - min2;
deba@2514
   555
      }
deba@2514
   556
        
deba@2514
   557
      int w = _data[v].parent;
deba@2514
   558
      _data[v].successor = _data[w].successor;
deba@2514
   559
      _data[w].successor = -1;
deba@2514
   560
      _data[v].parent = _data[w].parent;
deba@2514
   561
      _data[w].parent = v;
deba@2514
   562
      _data[w].right = _data[v].left;
deba@2514
   563
      _data[v].left = w;
deba@2514
   564
      if (_data[v].parent != -1){
deba@2514
   565
	if (_data[_data[v].parent].left == w) {
deba@2514
   566
	  _data[_data[v].parent].left = v;
deba@2514
   567
	} else {
deba@2514
   568
	  _data[_data[v].parent].right = v;
deba@2514
   569
	}
deba@2514
   570
      }
deba@2514
   571
      if (_data[w].right != -1){
deba@2514
   572
	_data[_data[w].right].parent = w;
deba@2514
   573
      }
deba@2514
   574
    }
deba@2514
   575
deba@2514
   576
  private:
deba@2514
   577
deba@2514
   578
    class ItemData {
deba@2514
   579
    public:
deba@2514
   580
      Item id;
deba@2514
   581
      int size;
deba@2514
   582
      int successor;
deba@2514
   583
      int parent;
deba@2514
   584
      int left;
deba@2514
   585
      int right;
deba@2514
   586
      Value dmin;
deba@2514
   587
      Value dcost;
deba@2514
   588
        
deba@2514
   589
    public:
deba@2514
   590
      ItemData(const Item &item)
deba@2514
   591
	: id(item), size(1), successor(), parent(-1), 
deba@2514
   592
	  left(-1), right(-1), dmin(0), dcost(0) {}
deba@2514
   593
    };
deba@2514
   594
     
deba@2514
   595
  };
deba@2514
   596
deba@2514
   597
  template <typename _Value, typename _ItemIntMap, typename _Tolerance>
deba@2514
   598
  class DynamicTree<_Value, _ItemIntMap, _Tolerance, false> {
deba@2514
   599
  public:
deba@2514
   600
    typedef _ItemIntMap ItemIntMap;
deba@2514
   601
    typedef typename ItemIntMap::Key Item;
deba@2514
   602
    typedef _Value Value;
deba@2514
   603
    typedef _Tolerance Tolerance;
deba@2514
   604
deba@2514
   605
  private:
deba@2514
   606
  
deba@2514
   607
    class ItemData;
deba@2514
   608
deba@2514
   609
    std::vector<ItemData> _data;
deba@2514
   610
    ItemIntMap &_iim;
deba@2514
   611
    Value _max_value;
deba@2514
   612
    Tolerance _tolerance;
deba@2514
   613
deba@2514
   614
  public:
deba@2514
   615
    DynamicTree(ItemIntMap &iim, const Tolerance& tolerance = Tolerance())
deba@2514
   616
      : _iim(iim), _max_value(std::numeric_limits<Value>::max()), 
deba@2514
   617
	_tolerance(tolerance) {}
deba@2514
   618
  
deba@2514
   619
    ~DynamicTree() {}
deba@2514
   620
deba@2514
   621
    void clear() {
deba@2514
   622
      _data.clear();
deba@2514
   623
    }
deba@2514
   624
deba@2514
   625
    void tolerance(const Tolerance& tolerance) const {
deba@2514
   626
      _tolerance = tolerance;
deba@2514
   627
      return *this;
deba@2514
   628
    } 
deba@2514
   629
  
deba@2514
   630
    const Tolerance& tolerance() const {
deba@2514
   631
      return tolerance;
deba@2514
   632
    } 
deba@2514
   633
  
deba@2514
   634
    void makeTree(const Item &item) {
deba@2514
   635
      _data[makePath(item)].successor = -1;
deba@2514
   636
    }
deba@2514
   637
    
deba@2514
   638
    Item findRoot(const Item &item) {
deba@2514
   639
      return _data[findTail(expose(_iim[item]))].id;
deba@2514
   640
    }
deba@2514
   641
    
deba@2514
   642
    Item findCost(const Item &item, Value& d){
deba@2514
   643
      return _data[findPathCost(expose(_iim[item]),d)].id;
deba@2514
   644
    }
deba@2514
   645
    
deba@2514
   646
    void addCost(const Item &item, Value x){
deba@2514
   647
      addPathCost(expose(_iim[item]), x);
deba@2514
   648
    }
deba@2514
   649
    
deba@2514
   650
    void link(const Item &item1, const Item &item2){
deba@2514
   651
      int v = _iim[item1];
deba@2514
   652
      int w = _iim[item2];
deba@2514
   653
      int p = expose(w);
deba@2514
   654
      join(-1, expose(v), p);
deba@2514
   655
      _data[v].successor = -1;
deba@2514
   656
    }    
deba@2514
   657
    
deba@2514
   658
    void cut(const Item &item) {
deba@2514
   659
      int v = _iim[item];
deba@2514
   660
      int p, q;
deba@2514
   661
      expose(v);
deba@2514
   662
      split(p, v, q);
deba@2514
   663
      if (p != -1) {
deba@2514
   664
	_data[p].successor = v;
deba@2514
   665
      }
deba@2514
   666
      if (q != -1) {
deba@2514
   667
	_data[q].successor = _data[v].successor;
deba@2514
   668
      }
deba@2514
   669
      _data[v].successor = -1;
deba@2514
   670
    }
deba@2514
   671
deba@2514
   672
    Item parent(const Item &item){
deba@2514
   673
      return _data[_iim[item].p].id;
deba@2514
   674
    }
deba@2514
   675
deba@2514
   676
    Value maxValue() const {
deba@2514
   677
      return _max_value;
deba@2514
   678
    }
deba@2514
   679
    
deba@2514
   680
  private:
deba@2514
   681
deba@2514
   682
    int makePath(const Item &item) {
deba@2514
   683
      _iim.set(item, _data.size());
deba@2514
   684
      ItemData v(item);
deba@2514
   685
      _data.push_back(v);
deba@2514
   686
      return _iim[item];
deba@2514
   687
    }
deba@2514
   688
deba@2514
   689
    int findPath(int v){
deba@2514
   690
      splay(v);
deba@2514
   691
      return v;
deba@2514
   692
    }
deba@2514
   693
    
deba@2514
   694
    int findPathCost(int p, Value &d){
deba@2514
   695
      while ((_data[p].right != -1 && 
deba@2514
   696
	      !_tolerance.less(0, _data[_data[p].right].dmin)) || 
deba@2514
   697
	     (_data[p].left != -1 && _tolerance.less(0, _data[p].dcost))) {
deba@2514
   698
	if (_data[p].right != -1 && 
deba@2514
   699
	    !_tolerance.less(0, _data[_data[p].right].dmin)) {
deba@2514
   700
	  p = _data[p].right;
deba@2514
   701
	} else if (_data[p].left != -1 && 
deba@2514
   702
		   !_tolerance.less(0, _data[_data[p].left].dmin)){
deba@2514
   703
	  p = _data[p].left;
deba@2514
   704
	}
deba@2514
   705
      }
deba@2514
   706
      splay(p);
deba@2514
   707
      d = _data[p].dmin;
deba@2514
   708
      return p; 
deba@2514
   709
    }
deba@2514
   710
deba@2514
   711
    int findTail(int p){
deba@2514
   712
      while (_data[p].right != -1) {
deba@2514
   713
	p = _data[p].right;
deba@2514
   714
      }
deba@2514
   715
      splay(p);
deba@2514
   716
      return p;
deba@2514
   717
    }
deba@2514
   718
    
deba@2514
   719
    void addPathCost(int p, Value x){
deba@2514
   720
      if (!_tolerance.less(x, _max_value)) {
deba@2514
   721
	_data[p].dmin = x;_data[p].dcost = x;
deba@2514
   722
      } else if (!_tolerance.less(-x, _max_value)) {
deba@2514
   723
	_data[p].dmin = 0;
deba@2514
   724
	_data[p].dcost = 0;
deba@2514
   725
      } else {
deba@2514
   726
	_data[p].dmin += x;
deba@2514
   727
      }
deba@2514
   728
    }
deba@2514
   729
deba@2514
   730
    void join(int p, int v, int q) {
deba@2514
   731
      Value min = _max_value;
deba@2514
   732
      Value pmin = _max_value;
deba@2514
   733
      Value vmin = _data[v].dmin;
deba@2514
   734
      Value qmin = _max_value;
deba@2514
   735
      if (p != -1){
deba@2514
   736
	pmin = _data[p].dmin;
deba@2514
   737
      }
deba@2514
   738
      if (q != -1){
deba@2514
   739
	qmin = _data[q].dmin;
deba@2514
   740
      }
deba@2514
   741
        
deba@2514
   742
      if (_tolerance.less(vmin, qmin)) {
deba@2514
   743
	if (_tolerance.less(vmin,pmin)) {
deba@2514
   744
	  min = vmin;
deba@2514
   745
	} else {
deba@2514
   746
	  min = pmin;
deba@2514
   747
	}
deba@2514
   748
      } else if (_tolerance.less(qmin,pmin)) {
deba@2514
   749
	min = qmin;
deba@2514
   750
      } else {
deba@2514
   751
	min = pmin;
deba@2514
   752
      }
deba@2514
   753
deba@2514
   754
      if (p != -1){
deba@2514
   755
	_data[p].parent = v;
deba@2514
   756
	_data[p].dmin -= min;
deba@2514
   757
      }
deba@2514
   758
      if (q!=-1){
deba@2514
   759
	_data[q].parent = v;
deba@2514
   760
	if (_tolerance.less(_data[q].dmin,_max_value)) {
deba@2514
   761
	  _data[q].dmin -= min;
deba@2514
   762
	}
deba@2514
   763
      }
deba@2514
   764
      _data[v].left = p;
deba@2514
   765
      _data[v].right = q;
deba@2514
   766
      if (_tolerance.less(min,_max_value)) {
deba@2514
   767
	_data[v].dcost = _data[v].dmin - min;
deba@2514
   768
      }
deba@2514
   769
      _data[v].dmin = min;
deba@2514
   770
    }
deba@2514
   771
deba@2514
   772
    void split(int &p, int v, int &q){
deba@2514
   773
      splay(v);
deba@2514
   774
      p = -1;
deba@2514
   775
      if (_data[v].left != -1){
deba@2514
   776
	p = _data[v].left;
deba@2514
   777
	_data[p].dmin += _data[v].dmin;
deba@2514
   778
	_data[p].parent = -1;
deba@2514
   779
	_data[v].left = -1;
deba@2514
   780
      }
deba@2514
   781
      q = -1;
deba@2514
   782
      if (_data[v].right != -1) {
deba@2514
   783
	q=_data[v].right;
deba@2514
   784
	if (_tolerance.less(_data[q].dmin, _max_value)) {
deba@2514
   785
	  _data[q].dmin += _data[v].dmin;
deba@2514
   786
	}
deba@2514
   787
	_data[q].parent = -1;
deba@2514
   788
	_data[v].right = -1;
deba@2514
   789
      } 
deba@2514
   790
      if (_tolerance.less(_data[v].dcost, _max_value)) {
deba@2514
   791
	_data[v].dmin += _data[v].dcost;
deba@2514
   792
	_data[v].dcost = 0;
deba@2514
   793
      } else {
deba@2514
   794
	_data[v].dmin = _data[v].dcost;
deba@2514
   795
      }
deba@2514
   796
    }
deba@2514
   797
 
deba@2514
   798
    int expose(int v) {
deba@2514
   799
      int p, q, r, w;
deba@2514
   800
      p = -1;
deba@2514
   801
      while (v != -1) {
deba@2514
   802
	w = _data[findPath(v)].successor;
deba@2514
   803
	split(q, v, r);
deba@2514
   804
	if (q != -1) {
deba@2514
   805
	  _data[q].successor = v;
deba@2514
   806
	}
deba@2514
   807
	join(p, v, r);
deba@2514
   808
	p = v;
deba@2514
   809
	v = w;
deba@2514
   810
      }
deba@2514
   811
      _data[p].successor = -1;
deba@2514
   812
      return p;
deba@2514
   813
    }
deba@2514
   814
deba@2514
   815
    void splay(int v) {
deba@2514
   816
      while (_data[v].parent != -1) {
deba@2514
   817
	if (v == _data[_data[v].parent].left) {
deba@2514
   818
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   819
	    zig(v);
deba@2514
   820
	  } else {
deba@2514
   821
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   822
	      zig(_data[v].parent);
deba@2514
   823
	      zig(v);
deba@2514
   824
	    } else {
deba@2514
   825
	      zig(v);
deba@2514
   826
	      zag(v);
deba@2514
   827
	    }
deba@2514
   828
	  }
deba@2514
   829
	} else {
deba@2514
   830
	  if (_data[_data[v].parent].parent == -1) {
deba@2514
   831
	    zag(v);
deba@2514
   832
	  } else {
deba@2514
   833
	    if (_data[v].parent == _data[_data[_data[v].parent].parent].left) {
deba@2514
   834
	      zag(v);
deba@2514
   835
	      zig(v);
deba@2514
   836
	    } else {
deba@2514
   837
	      zag(_data[v].parent);
deba@2514
   838
	      zag(v);
deba@2514
   839
	    }
deba@2514
   840
	  }
deba@2514
   841
	}
deba@2514
   842
      }
deba@2514
   843
    }
deba@2514
   844
deba@2514
   845
deba@2514
   846
    void zig(int v) {
deba@2514
   847
      Value min = _data[_data[v].parent].dmin;
deba@2514
   848
      int a = _data[v].parent;
deba@2514
   849
        
deba@2514
   850
      Value aa = _data[a].dcost;
deba@2514
   851
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   852
	aa+= min;
deba@2514
   853
      }
deba@2514
   854
deba@2514
   855
deba@2514
   856
      int b = v;
deba@2514
   857
      Value ab = min + _data[b].dmin;
deba@2514
   858
      Value bb = _data[b].dcost;
deba@2514
   859
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   860
	bb+= ab;
deba@2514
   861
      }
deba@2514
   862
deba@2514
   863
      int c = -1;
deba@2514
   864
      Value cc = _max_value;
deba@2514
   865
      if (_data[a].right != -1) {
deba@2514
   866
	c = _data[a].right;
deba@2514
   867
	cc = _data[c].dmin;
deba@2514
   868
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   869
	  cc+=min;
deba@2514
   870
	}
deba@2514
   871
      }
deba@2514
   872
deba@2514
   873
      int d = -1;
deba@2514
   874
      Value dd = _max_value;
deba@2514
   875
      if (_data[v].left != -1){
deba@2514
   876
	d = _data[v].left;
deba@2514
   877
	dd = ab + _data[d].dmin;
deba@2514
   878
      }
deba@2514
   879
deba@2514
   880
      int e = -1;
deba@2514
   881
      Value ee = _max_value;
deba@2514
   882
      if (_data[v].right != -1) {
deba@2514
   883
	e = _data[v].right;
deba@2514
   884
	ee = ab + _data[e].dmin;
deba@2514
   885
      }
deba@2514
   886
deba@2514
   887
      Value min2;
deba@2514
   888
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   889
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   890
	min2 = min;
deba@2514
   891
      } else {
deba@2514
   892
	if (_tolerance.less(aa, cc)) {
deba@2514
   893
	  if (_tolerance.less(aa, ee)) {
deba@2514
   894
	    min2 = aa;
deba@2514
   895
	  } else {
deba@2514
   896
	    min2 = ee;
deba@2514
   897
	  }
deba@2514
   898
	} else if (_tolerance.less(cc, ee)) {
deba@2514
   899
	  min2 = cc;
deba@2514
   900
	} else {
deba@2514
   901
	  min2 = ee;
deba@2514
   902
	}
deba@2514
   903
      }
deba@2514
   904
        
deba@2514
   905
      _data[a].dcost = aa;
deba@2514
   906
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   907
	_data[a].dcost -= min2;
deba@2514
   908
      }
deba@2514
   909
      _data[a].dmin = min2;
deba@2514
   910
      if (_tolerance.less(min2,_max_value)) { 
deba@2514
   911
	_data[a].dmin -= min; 
deba@2514
   912
      }
deba@2514
   913
      _data[b].dcost = bb;
deba@2514
   914
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
   915
	_data[b].dcost -= min;
deba@2514
   916
      }
deba@2514
   917
      _data[b].dmin = min;
deba@2514
   918
      if (c != -1) {
deba@2514
   919
	_data[c].dmin = cc;
deba@2514
   920
	if (_tolerance.less(cc, _max_value)) {
deba@2514
   921
	  _data[c].dmin -= min2;
deba@2514
   922
	}
deba@2514
   923
      }
deba@2514
   924
      if (d != -1) {
deba@2514
   925
	_data[d].dmin = dd - min;
deba@2514
   926
      }
deba@2514
   927
      if (e != -1) {
deba@2514
   928
	_data[e].dmin = ee - min2;
deba@2514
   929
      }
deba@2514
   930
        
deba@2514
   931
      int w = _data[v].parent;
deba@2514
   932
      _data[v].successor = _data[w].successor;
deba@2514
   933
      _data[w].successor = -1;
deba@2514
   934
      _data[v].parent = _data[w].parent;
deba@2514
   935
      _data[w].parent = v;
deba@2514
   936
      _data[w].left = _data[v].right;
deba@2514
   937
      _data[v].right = w;
deba@2514
   938
      if (_data[v].parent != -1){
deba@2514
   939
	if (_data[_data[v].parent].right == w) {
deba@2514
   940
	  _data[_data[v].parent].right = v;
deba@2514
   941
	} else {
deba@2514
   942
	  _data[_data[v].parent].left = v;
deba@2514
   943
	}
deba@2514
   944
      }
deba@2514
   945
      if (_data[w].left != -1){
deba@2514
   946
	_data[_data[w].left].parent = w;
deba@2514
   947
      }
deba@2514
   948
    }
deba@2514
   949
deba@2514
   950
deba@2514
   951
    void zag(int v) {
deba@2514
   952
deba@2514
   953
      Value min = _data[_data[v].parent].dmin;
deba@2514
   954
deba@2514
   955
      int a = _data[v].parent;
deba@2514
   956
      Value aa = _data[a].dcost;
deba@2514
   957
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
   958
	aa += min;
deba@2514
   959
      }
deba@2514
   960
        
deba@2514
   961
      int b = v;
deba@2514
   962
      Value ab = min + _data[b].dmin;
deba@2514
   963
      Value bb = _data[b].dcost;
deba@2514
   964
      if (_tolerance.less(bb, _max_value)) {
deba@2514
   965
	bb += ab;
deba@2514
   966
      }
deba@2514
   967
deba@2514
   968
      int c = -1;
deba@2514
   969
      Value cc = _max_value;
deba@2514
   970
      if (_data[a].left != -1){
deba@2514
   971
	c = _data[a].left;
deba@2514
   972
	cc = min + _data[c].dmin;
deba@2514
   973
      }
deba@2514
   974
deba@2514
   975
      int d = -1;
deba@2514
   976
      Value dd = _max_value;
deba@2514
   977
      if (_data[v].right!=-1) {
deba@2514
   978
	d = _data[v].right;
deba@2514
   979
	dd = _data[d].dmin;
deba@2514
   980
	if (_tolerance.less(dd, _max_value)) {
deba@2514
   981
	  dd += ab;
deba@2514
   982
	}
deba@2514
   983
      }
deba@2514
   984
deba@2514
   985
      int e = -1;
deba@2514
   986
      Value ee = _max_value;
deba@2514
   987
      if (_data[v].left != -1){
deba@2514
   988
	e = _data[v].left;
deba@2514
   989
	ee = ab + _data[e].dmin;
deba@2514
   990
      }
deba@2514
   991
deba@2514
   992
      Value min2;
deba@2514
   993
      if (_tolerance.less(0, _data[b].dmin) || 
deba@2514
   994
	  (e != -1 && !_tolerance.less(0, _data[e].dmin))) {
deba@2514
   995
	min2 = min;
deba@2514
   996
      } else {
deba@2514
   997
	if (_tolerance.less(aa, cc)) {
deba@2514
   998
	  if (_tolerance.less(aa, ee)) {
deba@2514
   999
	    min2 = aa;
deba@2514
  1000
	  } else {
deba@2514
  1001
	    min2 = ee;
deba@2514
  1002
	  }
deba@2514
  1003
	} else if (_tolerance.less(cc, ee)) {
deba@2514
  1004
	  min2 = cc;
deba@2514
  1005
	} else {
deba@2514
  1006
	  min2 = ee;
deba@2514
  1007
	}
deba@2514
  1008
      }
deba@2514
  1009
      _data[a].dcost = aa;
deba@2514
  1010
      if (_tolerance.less(aa, _max_value)) { 
deba@2514
  1011
	_data[a].dcost -= min2;
deba@2514
  1012
      }
deba@2514
  1013
      _data[a].dmin = min2;
deba@2514
  1014
      if (_tolerance.less(min2, _max_value)) {
deba@2514
  1015
	_data[a].dmin -= min;
deba@2514
  1016
      }
deba@2514
  1017
      _data[b].dcost = bb;
deba@2514
  1018
      if (_tolerance.less(bb, _max_value)) { 
deba@2514
  1019
	_data[b].dcost -= min;
deba@2514
  1020
      }
deba@2514
  1021
      _data[b].dmin = min;
deba@2514
  1022
      if (c != -1) {
deba@2514
  1023
	_data[c].dmin = cc - min2;
deba@2514
  1024
      }
deba@2514
  1025
      if (d != -1) {
deba@2514
  1026
	_data[d].dmin = dd;
deba@2514
  1027
	if (_tolerance.less(dd, _max_value)) {
deba@2514
  1028
	  _data[d].dmin -= min;
deba@2514
  1029
	}
deba@2514
  1030
      }
deba@2514
  1031
      if (e != -1) {
deba@2514
  1032
	_data[e].dmin = ee - min2;
deba@2514
  1033
      }
deba@2514
  1034
        
deba@2514
  1035
      int w = _data[v].parent;
deba@2514
  1036
      _data[v].successor = _data[w].successor;
deba@2514
  1037
      _data[w].successor = -1;
deba@2514
  1038
      _data[v].parent = _data[w].parent;
deba@2514
  1039
      _data[w].parent = v;
deba@2514
  1040
      _data[w].right = _data[v].left;
deba@2514
  1041
      _data[v].left = w;
deba@2514
  1042
      if (_data[v].parent != -1){
deba@2514
  1043
	if (_data[_data[v].parent].left == w) {
deba@2514
  1044
	  _data[_data[v].parent].left = v;
deba@2514
  1045
	} else {
deba@2514
  1046
	  _data[_data[v].parent].right = v;
deba@2514
  1047
	}
deba@2514
  1048
      }
deba@2514
  1049
      if (_data[w].right != -1){
deba@2514
  1050
	_data[_data[w].right].parent = w;
deba@2514
  1051
      }
deba@2514
  1052
    }
deba@2514
  1053
deba@2514
  1054
  private:
deba@2514
  1055
deba@2514
  1056
    class ItemData {
deba@2514
  1057
    public:
deba@2514
  1058
      Item id;
deba@2514
  1059
      int successor;
deba@2514
  1060
      int parent;
deba@2514
  1061
      int left;
deba@2514
  1062
      int right;
deba@2514
  1063
      Value dmin;
deba@2514
  1064
      Value dcost;
deba@2514
  1065
        
deba@2514
  1066
    public:
deba@2514
  1067
      ItemData(const Item &item)
deba@2514
  1068
	: id(item), successor(), parent(-1), 
deba@2514
  1069
	  left(-1), right(-1), dmin(0), dcost(0) {}
deba@2514
  1070
    };
deba@2514
  1071
     
deba@2514
  1072
  };
deba@2514
  1073
deba@2514
  1074
}
deba@2514
  1075
deba@2514
  1076
#endif