lemon/network_simplex.h
changeset 895 dca9eed2c375
parent 889 0bca98cbebbb
child 896 fb932bcfd803
equal deleted inserted replaced
31:ab65107fbc11 32:955f5986005d
   164     TEMPLATE_DIGRAPH_TYPEDEFS(GR);
   164     TEMPLATE_DIGRAPH_TYPEDEFS(GR);
   165 
   165 
   166     typedef std::vector<int> IntVector;
   166     typedef std::vector<int> IntVector;
   167     typedef std::vector<Value> ValueVector;
   167     typedef std::vector<Value> ValueVector;
   168     typedef std::vector<Cost> CostVector;
   168     typedef std::vector<Cost> CostVector;
   169     typedef std::vector<char> BoolVector;
   169     typedef std::vector<signed char> CharVector;
   170     // Note: vector<char> is used instead of vector<bool> for efficiency reasons
   170     // Note: vector<signed char> is used instead of vector<ArcState> and 
       
   171     // vector<ArcDirection> for efficiency reasons
   171 
   172 
   172     // State constants for arcs
   173     // State constants for arcs
   173     enum ArcState {
   174     enum ArcState {
   174       STATE_UPPER = -1,
   175       STATE_UPPER = -1,
   175       STATE_TREE  =  0,
   176       STATE_TREE  =  0,
   176       STATE_LOWER =  1
   177       STATE_LOWER =  1
   177     };
   178     };
   178 
   179 
   179     typedef std::vector<signed char> StateVector;
   180     // Direction constants for tree arcs
   180     // Note: vector<signed char> is used instead of vector<ArcState> for
   181     enum ArcDirection {
   181     // efficiency reasons
   182       DIR_DOWN = -1,
       
   183       DIR_UP   =  1
       
   184     };
   182 
   185 
   183   private:
   186   private:
   184 
   187 
   185     // Data related to the underlying digraph
   188     // Data related to the underlying digraph
   186     const GR &_graph;
   189     const GR &_graph;
   215     IntVector _pred;
   218     IntVector _pred;
   216     IntVector _thread;
   219     IntVector _thread;
   217     IntVector _rev_thread;
   220     IntVector _rev_thread;
   218     IntVector _succ_num;
   221     IntVector _succ_num;
   219     IntVector _last_succ;
   222     IntVector _last_succ;
       
   223     CharVector _pred_dir;
       
   224     CharVector _state;
   220     IntVector _dirty_revs;
   225     IntVector _dirty_revs;
   221     BoolVector _forward;
       
   222     StateVector _state;
       
   223     int _root;
   226     int _root;
   224 
   227 
   225     // Temporary data used in the current pivot iteration
   228     // Temporary data used in the current pivot iteration
   226     int in_arc, join, u_in, v_in, u_out, v_out;
   229     int in_arc, join, u_in, v_in, u_out, v_out;
   227     int first, second, right, last;
       
   228     int stem, par_stem, new_stem;
       
   229     Value delta;
   230     Value delta;
   230 
   231 
   231     const Value MAX;
   232     const Value MAX;
   232 
   233 
   233   public:
   234   public:
   248 
   249 
   249       // References to the NetworkSimplex class
   250       // References to the NetworkSimplex class
   250       const IntVector  &_source;
   251       const IntVector  &_source;
   251       const IntVector  &_target;
   252       const IntVector  &_target;
   252       const CostVector &_cost;
   253       const CostVector &_cost;
   253       const StateVector &_state;
   254       const CharVector &_state;
   254       const CostVector &_pi;
   255       const CostVector &_pi;
   255       int &_in_arc;
   256       int &_in_arc;
   256       int _search_arc_num;
   257       int _search_arc_num;
   257 
   258 
   258       // Pivot rule data
   259       // Pivot rule data
   300 
   301 
   301       // References to the NetworkSimplex class
   302       // References to the NetworkSimplex class
   302       const IntVector  &_source;
   303       const IntVector  &_source;
   303       const IntVector  &_target;
   304       const IntVector  &_target;
   304       const CostVector &_cost;
   305       const CostVector &_cost;
   305       const StateVector &_state;
   306       const CharVector &_state;
   306       const CostVector &_pi;
   307       const CostVector &_pi;
   307       int &_in_arc;
   308       int &_in_arc;
   308       int _search_arc_num;
   309       int _search_arc_num;
   309 
   310 
   310     public:
   311     public:
   339 
   340 
   340       // References to the NetworkSimplex class
   341       // References to the NetworkSimplex class
   341       const IntVector  &_source;
   342       const IntVector  &_source;
   342       const IntVector  &_target;
   343       const IntVector  &_target;
   343       const CostVector &_cost;
   344       const CostVector &_cost;
   344       const StateVector &_state;
   345       const CharVector &_state;
   345       const CostVector &_pi;
   346       const CostVector &_pi;
   346       int &_in_arc;
   347       int &_in_arc;
   347       int _search_arc_num;
   348       int _search_arc_num;
   348 
   349 
   349       // Pivot rule data
   350       // Pivot rule data
   412 
   413 
   413       // References to the NetworkSimplex class
   414       // References to the NetworkSimplex class
   414       const IntVector  &_source;
   415       const IntVector  &_source;
   415       const IntVector  &_target;
   416       const IntVector  &_target;
   416       const CostVector &_cost;
   417       const CostVector &_cost;
   417       const StateVector &_state;
   418       const CharVector &_state;
   418       const CostVector &_pi;
   419       const CostVector &_pi;
   419       int &_in_arc;
   420       int &_in_arc;
   420       int _search_arc_num;
   421       int _search_arc_num;
   421 
   422 
   422       // Pivot rule data
   423       // Pivot rule data
   515 
   516 
   516       // References to the NetworkSimplex class
   517       // References to the NetworkSimplex class
   517       const IntVector  &_source;
   518       const IntVector  &_source;
   518       const IntVector  &_target;
   519       const IntVector  &_target;
   519       const CostVector &_cost;
   520       const CostVector &_cost;
   520       const StateVector &_state;
   521       const CharVector &_state;
   521       const CostVector &_pi;
   522       const CostVector &_pi;
   522       int &_in_arc;
   523       int &_in_arc;
   523       int _search_arc_num;
   524       int _search_arc_num;
   524 
   525 
   525       // Pivot rule data
   526       // Pivot rule data
   568 
   569 
   569       // Find next entering arc
   570       // Find next entering arc
   570       bool findEnteringArc() {
   571       bool findEnteringArc() {
   571         // Check the current candidate list
   572         // Check the current candidate list
   572         int e;
   573         int e;
       
   574         Cost c;
   573         for (int i = 0; i != _curr_length; ++i) {
   575         for (int i = 0; i != _curr_length; ++i) {
   574           e = _candidates[i];
   576           e = _candidates[i];
   575           _cand_cost[e] = _state[e] *
   577           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   576             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   578           if (c < 0) {
   577           if (_cand_cost[e] >= 0) {
   579             _cand_cost[e] = c;
       
   580           } else {
   578             _candidates[i--] = _candidates[--_curr_length];
   581             _candidates[i--] = _candidates[--_curr_length];
   579           }
   582           }
   580         }
   583         }
   581 
   584 
   582         // Extend the list
   585         // Extend the list
   583         int cnt = _block_size;
   586         int cnt = _block_size;
   584         int limit = _head_length;
   587         int limit = _head_length;
   585 
   588 
   586         for (e = _next_arc; e != _search_arc_num; ++e) {
   589         for (e = _next_arc; e != _search_arc_num; ++e) {
   587           _cand_cost[e] = _state[e] *
   590           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   588             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
   591           if (c < 0) {
   589           if (_cand_cost[e] < 0) {
   592             _cand_cost[e] = c;
   590             _candidates[_curr_length++] = e;
   593             _candidates[_curr_length++] = e;
   591           }
   594           }
   592           if (--cnt == 0) {
   595           if (--cnt == 0) {
   593             if (_curr_length > limit) goto search_end;
   596             if (_curr_length > limit) goto search_end;
   594             limit = 0;
   597             limit = 0;
   911       _flow.resize(max_arc_num);
   914       _flow.resize(max_arc_num);
   912       _pi.resize(all_node_num);
   915       _pi.resize(all_node_num);
   913 
   916 
   914       _parent.resize(all_node_num);
   917       _parent.resize(all_node_num);
   915       _pred.resize(all_node_num);
   918       _pred.resize(all_node_num);
   916       _forward.resize(all_node_num);
   919       _pred_dir.resize(all_node_num);
   917       _thread.resize(all_node_num);
   920       _thread.resize(all_node_num);
   918       _rev_thread.resize(all_node_num);
   921       _rev_thread.resize(all_node_num);
   919       _succ_num.resize(all_node_num);
   922       _succ_num.resize(all_node_num);
   920       _last_succ.resize(all_node_num);
   923       _last_succ.resize(all_node_num);
   921       _state.resize(max_arc_num);
   924       _state.resize(max_arc_num);
  1114           _succ_num[u] = 1;
  1117           _succ_num[u] = 1;
  1115           _last_succ[u] = u;
  1118           _last_succ[u] = u;
  1116           _cap[e] = INF;
  1119           _cap[e] = INF;
  1117           _state[e] = STATE_TREE;
  1120           _state[e] = STATE_TREE;
  1118           if (_supply[u] >= 0) {
  1121           if (_supply[u] >= 0) {
  1119             _forward[u] = true;
  1122             _pred_dir[u] = DIR_UP;
  1120             _pi[u] = 0;
  1123             _pi[u] = 0;
  1121             _source[e] = u;
  1124             _source[e] = u;
  1122             _target[e] = _root;
  1125             _target[e] = _root;
  1123             _flow[e] = _supply[u];
  1126             _flow[e] = _supply[u];
  1124             _cost[e] = 0;
  1127             _cost[e] = 0;
  1125           } else {
  1128           } else {
  1126             _forward[u] = false;
  1129             _pred_dir[u] = DIR_DOWN;
  1127             _pi[u] = ART_COST;
  1130             _pi[u] = ART_COST;
  1128             _source[e] = _root;
  1131             _source[e] = _root;
  1129             _target[e] = u;
  1132             _target[e] = u;
  1130             _flow[e] = -_supply[u];
  1133             _flow[e] = -_supply[u];
  1131             _cost[e] = ART_COST;
  1134             _cost[e] = ART_COST;
  1141           _thread[u] = u + 1;
  1144           _thread[u] = u + 1;
  1142           _rev_thread[u + 1] = u;
  1145           _rev_thread[u + 1] = u;
  1143           _succ_num[u] = 1;
  1146           _succ_num[u] = 1;
  1144           _last_succ[u] = u;
  1147           _last_succ[u] = u;
  1145           if (_supply[u] >= 0) {
  1148           if (_supply[u] >= 0) {
  1146             _forward[u] = true;
  1149             _pred_dir[u] = DIR_UP;
  1147             _pi[u] = 0;
  1150             _pi[u] = 0;
  1148             _pred[u] = e;
  1151             _pred[u] = e;
  1149             _source[e] = u;
  1152             _source[e] = u;
  1150             _target[e] = _root;
  1153             _target[e] = _root;
  1151             _cap[e] = INF;
  1154             _cap[e] = INF;
  1152             _flow[e] = _supply[u];
  1155             _flow[e] = _supply[u];
  1153             _cost[e] = 0;
  1156             _cost[e] = 0;
  1154             _state[e] = STATE_TREE;
  1157             _state[e] = STATE_TREE;
  1155           } else {
  1158           } else {
  1156             _forward[u] = false;
  1159             _pred_dir[u] = DIR_DOWN;
  1157             _pi[u] = ART_COST;
  1160             _pi[u] = ART_COST;
  1158             _pred[u] = f;
  1161             _pred[u] = f;
  1159             _source[f] = _root;
  1162             _source[f] = _root;
  1160             _target[f] = u;
  1163             _target[f] = u;
  1161             _cap[f] = INF;
  1164             _cap[f] = INF;
  1182           _thread[u] = u + 1;
  1185           _thread[u] = u + 1;
  1183           _rev_thread[u + 1] = u;
  1186           _rev_thread[u + 1] = u;
  1184           _succ_num[u] = 1;
  1187           _succ_num[u] = 1;
  1185           _last_succ[u] = u;
  1188           _last_succ[u] = u;
  1186           if (_supply[u] <= 0) {
  1189           if (_supply[u] <= 0) {
  1187             _forward[u] = false;
  1190             _pred_dir[u] = DIR_DOWN;
  1188             _pi[u] = 0;
  1191             _pi[u] = 0;
  1189             _pred[u] = e;
  1192             _pred[u] = e;
  1190             _source[e] = _root;
  1193             _source[e] = _root;
  1191             _target[e] = u;
  1194             _target[e] = u;
  1192             _cap[e] = INF;
  1195             _cap[e] = INF;
  1193             _flow[e] = -_supply[u];
  1196             _flow[e] = -_supply[u];
  1194             _cost[e] = 0;
  1197             _cost[e] = 0;
  1195             _state[e] = STATE_TREE;
  1198             _state[e] = STATE_TREE;
  1196           } else {
  1199           } else {
  1197             _forward[u] = true;
  1200             _pred_dir[u] = DIR_UP;
  1198             _pi[u] = -ART_COST;
  1201             _pi[u] = -ART_COST;
  1199             _pred[u] = f;
  1202             _pred[u] = f;
  1200             _source[f] = u;
  1203             _source[f] = u;
  1201             _target[f] = _root;
  1204             _target[f] = _root;
  1202             _cap[f] = INF;
  1205             _cap[f] = INF;
  1235     // Find the leaving arc of the cycle and returns true if the
  1238     // Find the leaving arc of the cycle and returns true if the
  1236     // leaving arc is not the same as the entering arc
  1239     // leaving arc is not the same as the entering arc
  1237     bool findLeavingArc() {
  1240     bool findLeavingArc() {
  1238       // Initialize first and second nodes according to the direction
  1241       // Initialize first and second nodes according to the direction
  1239       // of the cycle
  1242       // of the cycle
       
  1243       int first, second;
  1240       if (_state[in_arc] == STATE_LOWER) {
  1244       if (_state[in_arc] == STATE_LOWER) {
  1241         first  = _source[in_arc];
  1245         first  = _source[in_arc];
  1242         second = _target[in_arc];
  1246         second = _target[in_arc];
  1243       } else {
  1247       } else {
  1244         first  = _target[in_arc];
  1248         first  = _target[in_arc];
  1245         second = _source[in_arc];
  1249         second = _source[in_arc];
  1246       }
  1250       }
  1247       delta = _cap[in_arc];
  1251       delta = _cap[in_arc];
  1248       int result = 0;
  1252       int result = 0;
  1249       Value d;
  1253       Value c, d;
  1250       int e;
  1254       int e;
  1251 
  1255 
  1252       // Search the cycle along the path form the first node to the root
  1256       // Search the cycle form the first node to the join node
  1253       for (int u = first; u != join; u = _parent[u]) {
  1257       for (int u = first; u != join; u = _parent[u]) {
  1254         e = _pred[u];
  1258         e = _pred[u];
  1255         d = _forward[u] ?
  1259         d = _flow[e];
  1256           _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
  1260         if (_pred_dir[u] == DIR_DOWN) {
       
  1261           c = _cap[e];
       
  1262           d = c >= MAX ? INF : c - d;
       
  1263         }
  1257         if (d < delta) {
  1264         if (d < delta) {
  1258           delta = d;
  1265           delta = d;
  1259           u_out = u;
  1266           u_out = u;
  1260           result = 1;
  1267           result = 1;
  1261         }
  1268         }
  1262       }
  1269       }
  1263       // Search the cycle along the path form the second node to the root
  1270 
       
  1271       // Search the cycle form the second node to the join node
  1264       for (int u = second; u != join; u = _parent[u]) {
  1272       for (int u = second; u != join; u = _parent[u]) {
  1265         e = _pred[u];
  1273         e = _pred[u];
  1266         d = _forward[u] ?
  1274         d = _flow[e];
  1267           (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
  1275         if (_pred_dir[u] == DIR_UP) {
       
  1276           c = _cap[e];
       
  1277           d = c >= MAX ? INF : c - d;
       
  1278         }
  1268         if (d <= delta) {
  1279         if (d <= delta) {
  1269           delta = d;
  1280           delta = d;
  1270           u_out = u;
  1281           u_out = u;
  1271           result = 2;
  1282           result = 2;
  1272         }
  1283         }
  1287       // Augment along the cycle
  1298       // Augment along the cycle
  1288       if (delta > 0) {
  1299       if (delta > 0) {
  1289         Value val = _state[in_arc] * delta;
  1300         Value val = _state[in_arc] * delta;
  1290         _flow[in_arc] += val;
  1301         _flow[in_arc] += val;
  1291         for (int u = _source[in_arc]; u != join; u = _parent[u]) {
  1302         for (int u = _source[in_arc]; u != join; u = _parent[u]) {
  1292           _flow[_pred[u]] += _forward[u] ? -val : val;
  1303           _flow[_pred[u]] -= _pred_dir[u] * val;
  1293         }
  1304         }
  1294         for (int u = _target[in_arc]; u != join; u = _parent[u]) {
  1305         for (int u = _target[in_arc]; u != join; u = _parent[u]) {
  1295           _flow[_pred[u]] += _forward[u] ? val : -val;
  1306           _flow[_pred[u]] += _pred_dir[u] * val;
  1296         }
  1307         }
  1297       }
  1308       }
  1298       // Update the state of the entering and leaving arcs
  1309       // Update the state of the entering and leaving arcs
  1299       if (change) {
  1310       if (change) {
  1300         _state[in_arc] = STATE_TREE;
  1311         _state[in_arc] = STATE_TREE;
  1305       }
  1316       }
  1306     }
  1317     }
  1307 
  1318 
  1308     // Update the tree structure
  1319     // Update the tree structure
  1309     void updateTreeStructure() {
  1320     void updateTreeStructure() {
  1310       int u, w;
       
  1311       int old_rev_thread = _rev_thread[u_out];
  1321       int old_rev_thread = _rev_thread[u_out];
  1312       int old_succ_num = _succ_num[u_out];
  1322       int old_succ_num = _succ_num[u_out];
  1313       int old_last_succ = _last_succ[u_out];
  1323       int old_last_succ = _last_succ[u_out];
  1314       v_out = _parent[u_out];
  1324       v_out = _parent[u_out];
  1315 
  1325 
  1316       u = _last_succ[u_in];  // the last successor of u_in
  1326       // Check if u_in and u_out coincide
  1317       right = _thread[u];    // the node after it
  1327       if (u_in == u_out) {
  1318 
  1328         // Update _parent, _pred, _pred_dir
  1319       // Handle the case when old_rev_thread equals to v_in
  1329         _parent[u_in] = v_in;
  1320       // (it also means that join and v_out coincide)
  1330         _pred[u_in] = in_arc;
  1321       if (old_rev_thread == v_in) {
  1331         _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
  1322         last = _thread[_last_succ[u_out]];
  1332 
       
  1333         // Update _thread and _rev_thread
       
  1334         if (_thread[v_in] != u_out) {
       
  1335           int after = _thread[old_last_succ];
       
  1336           _thread[old_rev_thread] = after;
       
  1337           _rev_thread[after] = old_rev_thread;
       
  1338           after = _thread[v_in];
       
  1339           _thread[v_in] = u_out;
       
  1340           _rev_thread[u_out] = v_in;
       
  1341           _thread[old_last_succ] = after;
       
  1342           _rev_thread[after] = old_last_succ;
       
  1343         }
  1323       } else {
  1344       } else {
  1324         last = _thread[v_in];
  1345         // Handle the case when old_rev_thread equals to v_in
  1325       }
  1346         // (it also means that join and v_out coincide)
  1326 
  1347         int thread_continue = old_rev_thread == v_in ?
  1327       // Update _thread and _parent along the stem nodes (i.e. the nodes
  1348           _thread[old_last_succ] : _thread[v_in];
  1328       // between u_in and u_out, whose parent have to be changed)
  1349 
  1329       _thread[v_in] = stem = u_in;
  1350         // Update _thread and _parent along the stem nodes (i.e. the nodes
  1330       _dirty_revs.clear();
  1351         // between u_in and u_out, whose parent have to be changed)
  1331       _dirty_revs.push_back(v_in);
  1352         int stem = u_in;              // the current stem node
  1332       par_stem = v_in;
  1353         int par_stem = v_in;          // the new parent of stem
  1333       while (stem != u_out) {
  1354         int next_stem;                // the next stem node
  1334         // Insert the next stem node into the thread list
  1355         int last = _last_succ[u_in];  // the last successor of stem
  1335         new_stem = _parent[stem];
  1356         int before, after = _thread[last];
  1336         _thread[u] = new_stem;
  1357         _thread[v_in] = u_in;
  1337         _dirty_revs.push_back(u);
  1358         _dirty_revs.clear();
  1338 
  1359         _dirty_revs.push_back(v_in);
  1339         // Remove the subtree of stem from the thread list
  1360         while (stem != u_out) {
  1340         w = _rev_thread[stem];
  1361           // Insert the next stem node into the thread list
  1341         _thread[w] = right;
  1362           next_stem = _parent[stem];
  1342         _rev_thread[right] = w;
  1363           _thread[last] = next_stem;
  1343 
  1364           _dirty_revs.push_back(last);
  1344         // Change the parent node and shift stem nodes
  1365 
  1345         _parent[stem] = par_stem;
  1366           // Remove the subtree of stem from the thread list
  1346         par_stem = stem;
  1367           before = _rev_thread[stem];
  1347         stem = new_stem;
  1368           _thread[before] = after;
  1348 
  1369           _rev_thread[after] = before;
  1349         // Update u and right
  1370 
  1350         u = _last_succ[stem] == _last_succ[par_stem] ?
  1371           // Change the parent node and shift stem nodes
  1351           _rev_thread[par_stem] : _last_succ[stem];
  1372           _parent[stem] = par_stem;
  1352         right = _thread[u];
  1373           par_stem = stem;
  1353       }
  1374           stem = next_stem;
  1354       _parent[u_out] = par_stem;
  1375 
  1355       _thread[u] = last;
  1376           // Update last and after
  1356       _rev_thread[last] = u;
  1377           last = _last_succ[stem] == _last_succ[par_stem] ?
  1357       _last_succ[u_out] = u;
  1378             _rev_thread[par_stem] : _last_succ[stem];
  1358 
  1379           after = _thread[last];
  1359       // Remove the subtree of u_out from the thread list except for
  1380         }
  1360       // the case when old_rev_thread equals to v_in
  1381         _parent[u_out] = par_stem;
  1361       // (it also means that join and v_out coincide)
  1382         _thread[last] = thread_continue;
  1362       if (old_rev_thread != v_in) {
  1383         _rev_thread[thread_continue] = last;
  1363         _thread[old_rev_thread] = right;
  1384         _last_succ[u_out] = last;
  1364         _rev_thread[right] = old_rev_thread;
  1385 
  1365       }
  1386         // Remove the subtree of u_out from the thread list except for
  1366 
  1387         // the case when old_rev_thread equals to v_in
  1367       // Update _rev_thread using the new _thread values
  1388         if (old_rev_thread != v_in) {
  1368       for (int i = 0; i != int(_dirty_revs.size()); ++i) {
  1389           _thread[old_rev_thread] = after;
  1369         u = _dirty_revs[i];
  1390           _rev_thread[after] = old_rev_thread;
  1370         _rev_thread[_thread[u]] = u;
  1391         }
  1371       }
  1392 
  1372 
  1393         // Update _rev_thread using the new _thread values
  1373       // Update _pred, _forward, _last_succ and _succ_num for the
  1394         for (int i = 0; i != int(_dirty_revs.size()); ++i) {
  1374       // stem nodes from u_out to u_in
  1395           int u = _dirty_revs[i];
  1375       int tmp_sc = 0, tmp_ls = _last_succ[u_out];
  1396           _rev_thread[_thread[u]] = u;
  1376       u = u_out;
  1397         }
  1377       while (u != u_in) {
  1398 
  1378         w = _parent[u];
  1399         // Update _pred, _pred_dir, _last_succ and _succ_num for the
  1379         _pred[u] = _pred[w];
  1400         // stem nodes from u_out to u_in
  1380         _forward[u] = !_forward[w];
  1401         int tmp_sc = 0, tmp_ls = _last_succ[u_out];
  1381         tmp_sc += _succ_num[u] - _succ_num[w];
  1402         for (int u = u_out, p = _parent[u]; u != u_in; u = p, p = _parent[u]) {
  1382         _succ_num[u] = tmp_sc;
  1403           _pred[u] = _pred[p];
  1383         _last_succ[w] = tmp_ls;
  1404           _pred_dir[u] = -_pred_dir[p];
  1384         u = w;
  1405           tmp_sc += _succ_num[u] - _succ_num[p];
  1385       }
  1406           _succ_num[u] = tmp_sc;
  1386       _pred[u_in] = in_arc;
  1407           _last_succ[p] = tmp_ls;
  1387       _forward[u_in] = (u_in == _source[in_arc]);
  1408         }
  1388       _succ_num[u_in] = old_succ_num;
  1409         _pred[u_in] = in_arc;
  1389 
  1410         _pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;
  1390       // Set limits for updating _last_succ form v_in and v_out
  1411         _succ_num[u_in] = old_succ_num;
  1391       // towards the root
       
  1392       int up_limit_in = -1;
       
  1393       int up_limit_out = -1;
       
  1394       if (_last_succ[join] == v_in) {
       
  1395         up_limit_out = join;
       
  1396       } else {
       
  1397         up_limit_in = join;
       
  1398       }
  1412       }
  1399 
  1413 
  1400       // Update _last_succ from v_in towards the root
  1414       // Update _last_succ from v_in towards the root
  1401       for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
  1415       int up_limit_out = _last_succ[join] == v_in ? join : -1;
  1402            u = _parent[u]) {
  1416       int last_succ_out = _last_succ[u_out];
  1403         _last_succ[u] = _last_succ[u_out];
  1417       for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) {
  1404       }
  1418         _last_succ[u] = last_succ_out;
       
  1419       }
       
  1420 
  1405       // Update _last_succ from v_out towards the root
  1421       // Update _last_succ from v_out towards the root
  1406       if (join != old_rev_thread && v_in != old_rev_thread) {
  1422       if (join != old_rev_thread && v_in != old_rev_thread) {
  1407         for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1423         for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1408              u = _parent[u]) {
  1424              u = _parent[u]) {
  1409           _last_succ[u] = old_rev_thread;
  1425           _last_succ[u] = old_rev_thread;
  1410         }
  1426         }
  1411       } else {
  1427       }
  1412         for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1428       else if (last_succ_out != old_last_succ) {
       
  1429         for (int u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
  1413              u = _parent[u]) {
  1430              u = _parent[u]) {
  1414           _last_succ[u] = _last_succ[u_out];
  1431           _last_succ[u] = last_succ_out;
  1415         }
  1432         }
  1416       }
  1433       }
  1417 
  1434 
  1418       // Update _succ_num from v_in to join
  1435       // Update _succ_num from v_in to join
  1419       for (u = v_in; u != join; u = _parent[u]) {
  1436       for (int u = v_in; u != join; u = _parent[u]) {
  1420         _succ_num[u] += old_succ_num;
  1437         _succ_num[u] += old_succ_num;
  1421       }
  1438       }
  1422       // Update _succ_num from v_out to join
  1439       // Update _succ_num from v_out to join
  1423       for (u = v_out; u != join; u = _parent[u]) {
  1440       for (int u = v_out; u != join; u = _parent[u]) {
  1424         _succ_num[u] -= old_succ_num;
  1441         _succ_num[u] -= old_succ_num;
  1425       }
  1442       }
  1426     }
  1443     }
  1427 
  1444 
  1428     // Update potentials
  1445     // Update potentials in the subtree that has been moved
  1429     void updatePotential() {
  1446     void updatePotential() {
  1430       Cost sigma = _forward[u_in] ?
  1447       Cost sigma = _pi[v_in] - _pi[u_in] -
  1431         _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
  1448                    _pred_dir[u_in] * _cost[in_arc];
  1432         _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
       
  1433       // Update potentials in the subtree, which has been moved
       
  1434       int end = _thread[_last_succ[u_in]];
  1449       int end = _thread[_last_succ[u_in]];
  1435       for (int u = u_in; u != end; u = _thread[u]) {
  1450       for (int u = u_in; u != end; u = _thread[u]) {
  1436         _pi[u] += sigma;
  1451         _pi[u] += sigma;
  1437       }
  1452       }
  1438     }
  1453     }