lemon/dynamic_tree.h
author kpeter
Mon, 18 Feb 2008 03:30:12 +0000
changeset 2573 a9758ea1f01c
parent 2519 a7376f7ed899
permissions -rw-r--r--
Improvements in CycleCanceling.

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