gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
GCC 3.3 compatibility fix in nagamochi_ibaraki.h
0 1 0
default
1 file changed with 6 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 6144 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2010
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_NAGAMOCHI_IBARAKI_H
20 20
#define LEMON_NAGAMOCHI_IBARAKI_H
21 21

	
22 22

	
23 23
/// \ingroup min_cut
24 24
/// \file
25 25
/// \brief Implementation of the Nagamochi-Ibaraki algorithm.
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/bin_heap.h>
29 29
#include <lemon/bucket_heap.h>
30 30
#include <lemon/maps.h>
31 31
#include <lemon/radix_sort.h>
32 32
#include <lemon/unionfind.h>
33 33

	
34 34
#include <cassert>
35 35

	
36 36
namespace lemon {
37 37

	
38 38
  /// \brief Default traits class for NagamochiIbaraki class.
39 39
  ///
40 40
  /// Default traits class for NagamochiIbaraki class.
41 41
  /// \param GR The undirected graph type.
42 42
  /// \param CM Type of capacity map.
43 43
  template <typename GR, typename CM>
44 44
  struct NagamochiIbarakiDefaultTraits {
45 45
    /// The type of the capacity map.
46 46
    typedef typename CM::Value Value;
47 47

	
48 48
    /// The undirected graph type the algorithm runs on.
49 49
    typedef GR Graph;
50 50

	
51 51
    /// \brief The type of the map that stores the edge capacities.
52 52
    ///
53 53
    /// The type of the map that stores the edge capacities.
54 54
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
55 55
    typedef CM CapacityMap;
56 56

	
57 57
    /// \brief Instantiates a CapacityMap.
58 58
    ///
59 59
    /// This function instantiates a \ref CapacityMap.
60 60
#ifdef DOXYGEN
61 61
    static CapacityMap *createCapacityMap(const Graph& graph)
62 62
#else
63 63
    static CapacityMap *createCapacityMap(const Graph&)
64 64
#endif
65 65
    {
66 66
        LEMON_ASSERT(false, "CapacityMap is not initialized");
67 67
        return 0; // ignore warnings
68 68
    }
69 69

	
70 70
    /// \brief The cross reference type used by heap.
71 71
    ///
72 72
    /// The cross reference type used by heap.
73 73
    /// Usually \c Graph::NodeMap<int>.
74 74
    typedef typename Graph::template NodeMap<int> HeapCrossRef;
75 75

	
76 76
    /// \brief Instantiates a HeapCrossRef.
77 77
    ///
78 78
    /// This function instantiates a \ref HeapCrossRef.
79 79
    /// \param g is the graph, to which we would like to define the
80 80
    /// \ref HeapCrossRef.
81 81
    static HeapCrossRef *createHeapCrossRef(const Graph& g) {
82 82
      return new HeapCrossRef(g);
83 83
    }
84 84

	
85 85
    /// \brief The heap type used by NagamochiIbaraki algorithm.
86 86
    ///
87 87
    /// The heap type used by NagamochiIbaraki algorithm. It has to
88 88
    /// maximize the priorities.
89 89
    ///
90 90
    /// \sa BinHeap
91 91
    /// \sa NagamochiIbaraki
92 92
    typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
93 93

	
94 94
    /// \brief Instantiates a Heap.
95 95
    ///
96 96
    /// This function instantiates a \ref Heap.
97 97
    /// \param r is the cross reference of the heap.
98 98
    static Heap *createHeap(HeapCrossRef& r) {
99 99
      return new Heap(r);
100 100
    }
101 101
  };
102 102

	
103 103
  /// \ingroup min_cut
104 104
  ///
105 105
  /// \brief Calculates the minimum cut in an undirected graph.
106 106
  ///
107 107
  /// Calculates the minimum cut in an undirected graph with the
108 108
  /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
109 109
  /// nodes into two partitions with the minimum sum of edge capacities
110 110
  /// between the two partitions. The algorithm can be used to test
111 111
  /// the network reliability, especially to test how many links have
112 112
  /// to be destroyed in the network to split it to at least two
113 113
  /// distinict subnetworks.
114 114
  ///
115 115
  /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
116 116
  /// \ref FibHeap "Fibonacci heap" it can be decreased to
117 117
  /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
118 118
  /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
119 119
  /// complexity.
120 120
  ///
121 121
  /// \warning The value type of the capacity map should be able to
122 122
  /// hold any cut value of the graph, otherwise the result can
123 123
  /// overflow.
124 124
  /// \note This capacity is supposed to be integer type.
125 125
#ifdef DOXYGEN
126 126
  template <typename GR, typename CM, typename TR>
127 127
#else
128 128
  template <typename GR,
129 129
            typename CM = typename GR::template EdgeMap<int>,
130 130
            typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
131 131
#endif
132 132
  class NagamochiIbaraki {
133 133
  public:
134 134

	
135 135
    typedef TR Traits;
136 136
    /// The type of the underlying graph.
137 137
    typedef typename Traits::Graph Graph;
138 138

	
139 139
    /// The type of the capacity map.
140 140
    typedef typename Traits::CapacityMap CapacityMap;
141 141
    /// The value type of the capacity map.
142 142
    typedef typename Traits::CapacityMap::Value Value;
143 143

	
144 144
    /// The heap type used by the algorithm.
145 145
    typedef typename Traits::Heap Heap;
146 146
    /// The cross reference type used for the heap.
147 147
    typedef typename Traits::HeapCrossRef HeapCrossRef;
148 148

	
149 149
    ///\name Named template parameters
150 150

	
151 151
    ///@{
152 152

	
153 153
    struct SetUnitCapacityTraits : public Traits {
154 154
      typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
155 155
      static CapacityMap *createCapacityMap(const Graph&) {
156 156
        return new CapacityMap();
157 157
      }
158 158
    };
159 159

	
160 160
    /// \brief \ref named-templ-param "Named parameter" for setting
161 161
    /// the capacity map to a constMap<Edge, int, 1>() instance
162 162
    ///
163 163
    /// \ref named-templ-param "Named parameter" for setting
164 164
    /// the capacity map to a constMap<Edge, int, 1>() instance
165 165
    struct SetUnitCapacity
166 166
      : public NagamochiIbaraki<Graph, CapacityMap,
167 167
                                SetUnitCapacityTraits> {
168 168
      typedef NagamochiIbaraki<Graph, CapacityMap,
169 169
                               SetUnitCapacityTraits> Create;
170 170
    };
171 171

	
172 172

	
173 173
    template <class H, class CR>
174 174
    struct SetHeapTraits : public Traits {
175 175
      typedef CR HeapCrossRef;
176 176
      typedef H Heap;
177 177
      static HeapCrossRef *createHeapCrossRef(int num) {
178 178
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
179 179
        return 0; // ignore warnings
180 180
      }
181 181
      static Heap *createHeap(HeapCrossRef &) {
182 182
        LEMON_ASSERT(false, "Heap is not initialized");
183 183
        return 0; // ignore warnings
184 184
      }
185 185
    };
186 186

	
187 187
    /// \brief \ref named-templ-param "Named parameter" for setting
188 188
    /// heap and cross reference type
189 189
    ///
190 190
    /// \ref named-templ-param "Named parameter" for setting heap and
191 191
    /// cross reference type. The heap has to maximize the priorities.
192 192
    template <class H, class CR = RangeMap<int> >
193 193
    struct SetHeap
194 194
      : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
195 195
      typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
196 196
      Create;
197 197
    };
198 198

	
199 199
    template <class H, class CR>
200 200
    struct SetStandardHeapTraits : public Traits {
201 201
      typedef CR HeapCrossRef;
202 202
      typedef H Heap;
203 203
      static HeapCrossRef *createHeapCrossRef(int size) {
204 204
        return new HeapCrossRef(size);
205 205
      }
206 206
      static Heap *createHeap(HeapCrossRef &crossref) {
207 207
        return new Heap(crossref);
208 208
      }
209 209
    };
210 210

	
211 211
    /// \brief \ref named-templ-param "Named parameter" for setting
212 212
    /// heap and cross reference type with automatic allocation
213 213
    ///
214 214
    /// \ref named-templ-param "Named parameter" for setting heap and
215 215
    /// cross reference type with automatic allocation. They should
216 216
    /// have standard constructor interfaces to be able to
217 217
    /// automatically created by the algorithm (i.e. the graph should
218 218
    /// be passed to the constructor of the cross reference and the
219 219
    /// cross reference should be passed to the constructor of the
220 220
    /// heap). However, external heap and cross reference objects
221 221
    /// could also be passed to the algorithm using the \ref heap()
222 222
    /// function before calling \ref run() or \ref init(). The heap
223 223
    /// has to maximize the priorities.
224 224
    /// \sa SetHeap
225 225
    template <class H, class CR = RangeMap<int> >
226 226
    struct SetStandardHeap
227 227
      : public NagamochiIbaraki<Graph, CapacityMap,
228 228
                                SetStandardHeapTraits<H, CR> > {
229 229
      typedef NagamochiIbaraki<Graph, CapacityMap,
230 230
                               SetStandardHeapTraits<H, CR> > Create;
231 231
    };
232 232

	
233 233
    ///@}
234 234

	
235 235

	
236 236
  private:
237 237

	
238 238
    const Graph &_graph;
239 239
    const CapacityMap *_capacity;
240 240
    bool _local_capacity; // unit capacity
241 241

	
242 242
    struct ArcData {
243 243
      typename Graph::Node target;
244 244
      int prev, next;
245 245
    };
246 246
    struct EdgeData {
247 247
      Value capacity;
248 248
      Value cut;
249 249
    };
250 250

	
251 251
    struct NodeData {
252 252
      int first_arc;
253 253
      typename Graph::Node prev, next;
254 254
      int curr_arc;
255 255
      typename Graph::Node last_rep;
256 256
      Value sum;
257 257
    };
258 258

	
259 259
    typename Graph::template NodeMap<NodeData> *_nodes;
260 260
    std::vector<ArcData> _arcs;
261 261
    std::vector<EdgeData> _edges;
262 262

	
263 263
    typename Graph::Node _first_node;
264 264
    int _node_num;
265 265

	
266 266
    Value _min_cut;
267 267

	
268 268
    HeapCrossRef *_heap_cross_ref;
269 269
    bool _local_heap_cross_ref;
270 270
    Heap *_heap;
271 271
    bool _local_heap;
272 272

	
273 273
    typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
274 274
    NodeList *_next_rep;
275 275

	
276 276
    typedef typename Graph::template NodeMap<bool> MinCutMap;
277 277
    MinCutMap *_cut_map;
278 278

	
279 279
    void createStructures() {
280 280
      if (!_nodes) {
281 281
        _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
282 282
      }
283 283
      if (!_capacity) {
284 284
        _local_capacity = true;
285 285
        _capacity = Traits::createCapacityMap(_graph);
286 286
      }
287 287
      if (!_heap_cross_ref) {
288 288
        _local_heap_cross_ref = true;
289 289
        _heap_cross_ref = Traits::createHeapCrossRef(_graph);
290 290
      }
291 291
      if (!_heap) {
292 292
        _local_heap = true;
293 293
        _heap = Traits::createHeap(*_heap_cross_ref);
294 294
      }
295 295
      if (!_next_rep) {
296 296
        _next_rep = new NodeList(_graph);
297 297
      }
298 298
      if (!_cut_map) {
299 299
        _cut_map = new MinCutMap(_graph);
300 300
      }
301 301
    }
302 302

	
303
  public :
303
  protected:
304
    //This is here to avoid a gcc-3.3 compilation error.
305
    //It should never be called.
306
    NagamochiIbaraki() {} 
307
    
308
  public:
304 309

	
305 310
    typedef NagamochiIbaraki Create;
306 311

	
307 312

	
308 313
    /// \brief Constructor.
309 314
    ///
310 315
    /// \param graph The graph the algorithm runs on.
311 316
    /// \param capacity The capacity map used by the algorithm.
312 317
    NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
313 318
      : _graph(graph), _capacity(&capacity), _local_capacity(false),
314 319
        _nodes(0), _arcs(), _edges(), _min_cut(),
315 320
        _heap_cross_ref(0), _local_heap_cross_ref(false),
316 321
        _heap(0), _local_heap(false),
317 322
        _next_rep(0), _cut_map(0) {}
318 323

	
319 324
    /// \brief Constructor.
320 325
    ///
321 326
    /// This constructor can be used only when the Traits class
322 327
    /// defines how can the local capacity map be instantiated.
323 328
    /// If the SetUnitCapacity used the algorithm automatically
324 329
    /// constructs the capacity map.
325 330
    ///
326 331
    ///\param graph The graph the algorithm runs on.
327 332
    NagamochiIbaraki(const Graph& graph)
328 333
      : _graph(graph), _capacity(0), _local_capacity(false),
329 334
        _nodes(0), _arcs(), _edges(), _min_cut(),
330 335
        _heap_cross_ref(0), _local_heap_cross_ref(false),
331 336
        _heap(0), _local_heap(false),
332 337
        _next_rep(0), _cut_map(0) {}
333 338

	
334 339
    /// \brief Destructor.
335 340
    ///
336 341
    /// Destructor.
337 342
    ~NagamochiIbaraki() {
338 343
      if (_local_capacity) delete _capacity;
339 344
      if (_nodes) delete _nodes;
340 345
      if (_local_heap) delete _heap;
341 346
      if (_local_heap_cross_ref) delete _heap_cross_ref;
342 347
      if (_next_rep) delete _next_rep;
343 348
      if (_cut_map) delete _cut_map;
344 349
    }
345 350

	
346 351
    /// \brief Sets the heap and the cross reference used by algorithm.
347 352
    ///
348 353
    /// Sets the heap and the cross reference used by algorithm.
349 354
    /// If you don't use this function before calling \ref run(),
350 355
    /// it will allocate one. The destuctor deallocates this
351 356
    /// automatically allocated heap and cross reference, of course.
352 357
    /// \return <tt> (*this) </tt>
353 358
    NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
354 359
    {
355 360
      if (_local_heap_cross_ref) {
356 361
        delete _heap_cross_ref;
357 362
        _local_heap_cross_ref = false;
358 363
      }
359 364
      _heap_cross_ref = &cr;
360 365
      if (_local_heap) {
361 366
        delete _heap;
362 367
        _local_heap = false;
363 368
      }
364 369
      _heap = &hp;
365 370
      return *this;
366 371
    }
367 372

	
368 373
    /// \name Execution control
369 374
    /// The simplest way to execute the algorithm is to use
370 375
    /// one of the member functions called \c run().
371 376
    /// \n
372 377
    /// If you need more control on the execution,
373 378
    /// first you must call \ref init() and then call the start()
374 379
    /// or proper times the processNextPhase() member functions.
375 380

	
376 381
    ///@{
377 382

	
378 383
    /// \brief Initializes the internal data structures.
379 384
    ///
380 385
    /// Initializes the internal data structures.
381 386
    void init() {
382 387
      createStructures();
383 388

	
384 389
      int edge_num = countEdges(_graph);
385 390
      _edges.resize(edge_num);
386 391
      _arcs.resize(2 * edge_num);
387 392

	
388 393
      typename Graph::Node prev = INVALID;
389 394
      _node_num = 0;
390 395
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
391 396
        (*_cut_map)[n] = false;
392 397
        (*_next_rep)[n] = INVALID;
393 398
        (*_nodes)[n].last_rep = n;
394 399
        (*_nodes)[n].first_arc = -1;
395 400
        (*_nodes)[n].curr_arc = -1;
396 401
        (*_nodes)[n].prev = prev;
397 402
        if (prev != INVALID) {
398 403
          (*_nodes)[prev].next = n;
399 404
        }
400 405
        (*_nodes)[n].next = INVALID;
401 406
        (*_nodes)[n].sum = 0;
402 407
        prev = n;
403 408
        ++_node_num;
404 409
      }
405 410

	
406 411
      _first_node = typename Graph::NodeIt(_graph);
407 412

	
408 413
      int index = 0;
409 414
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
410 415
        for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
411 416
          typename Graph::Node m = _graph.target(a);
412 417
          
413 418
          if (!(n < m)) continue;
414 419

	
415 420
          (*_nodes)[n].sum += (*_capacity)[a];
416 421
          (*_nodes)[m].sum += (*_capacity)[a];
417 422
          
418 423
          int c = (*_nodes)[m].curr_arc;
419 424
          if (c != -1 && _arcs[c ^ 1].target == n) {
420 425
            _edges[c >> 1].capacity += (*_capacity)[a];
421 426
          } else {
422 427
            _edges[index].capacity = (*_capacity)[a];
423 428
            
424 429
            _arcs[index << 1].prev = -1;
425 430
            if ((*_nodes)[n].first_arc != -1) {
426 431
              _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
427 432
            }
428 433
            _arcs[index << 1].next = (*_nodes)[n].first_arc;
429 434
            (*_nodes)[n].first_arc = (index << 1);
430 435
            _arcs[index << 1].target = m;
431 436

	
432 437
            (*_nodes)[m].curr_arc = (index << 1);
433 438
            
434 439
            _arcs[(index << 1) | 1].prev = -1;
435 440
            if ((*_nodes)[m].first_arc != -1) {
436 441
              _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
437 442
            }
438 443
            _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
439 444
            (*_nodes)[m].first_arc = ((index << 1) | 1);
440 445
            _arcs[(index << 1) | 1].target = n;
441 446
            
442 447
            ++index;
443 448
          }
444 449
        }
445 450
      }
446 451

	
447 452
      typename Graph::Node cut_node = INVALID;
448 453
      _min_cut = std::numeric_limits<Value>::max();
449 454

	
450 455
      for (typename Graph::Node n = _first_node; 
451 456
           n != INVALID; n = (*_nodes)[n].next) {
452 457
        if ((*_nodes)[n].sum < _min_cut) {
453 458
          cut_node = n;
454 459
          _min_cut = (*_nodes)[n].sum;
455 460
        }
456 461
      }
457 462
      (*_cut_map)[cut_node] = true;
458 463
      if (_min_cut == 0) {
459 464
        _first_node = INVALID;
460 465
      }
461 466
    }
462 467

	
463 468
  public:
464 469

	
465 470
    /// \brief Processes the next phase
466 471
    ///
467 472
    /// Processes the next phase in the algorithm. It must be called
468 473
    /// at most one less the number of the nodes in the graph.
469 474
    ///
470 475
    ///\return %True when the algorithm finished.
471 476
    bool processNextPhase() {
472 477
      if (_first_node == INVALID) return true;
473 478

	
474 479
      _heap->clear();
475 480
      for (typename Graph::Node n = _first_node; 
476 481
           n != INVALID; n = (*_nodes)[n].next) {
477 482
        (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
478 483
      }
479 484

	
480 485
      std::vector<typename Graph::Node> order;
481 486
      order.reserve(_node_num);
482 487
      int sep = 0;
483 488

	
484 489
      Value alpha = 0;
485 490
      Value pmc = std::numeric_limits<Value>::max();
486 491

	
487 492
      _heap->push(_first_node, static_cast<Value>(0));
488 493
      while (!_heap->empty()) {
489 494
        typename Graph::Node n = _heap->top();
490 495
        Value v = _heap->prio();
491 496

	
492 497
        _heap->pop();
493 498
        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
494 499
          switch (_heap->state(_arcs[a].target)) {
495 500
          case Heap::PRE_HEAP: 
496 501
            {
497 502
              Value nv = _edges[a >> 1].capacity;
498 503
              _heap->push(_arcs[a].target, nv);
499 504
              _edges[a >> 1].cut = nv;
500 505
            } break;
501 506
          case Heap::IN_HEAP:
502 507
            {
503 508
              Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
504 509
              _heap->decrease(_arcs[a].target, nv);
505 510
              _edges[a >> 1].cut = nv;
506 511
            } break;
507 512
          case Heap::POST_HEAP:
508 513
            break;
509 514
          }
510 515
        }
511 516

	
512 517
        alpha += (*_nodes)[n].sum;
513 518
        alpha -= 2 * v;
514 519

	
515 520
        order.push_back(n);
516 521
        if (!_heap->empty()) {
517 522
          if (alpha < pmc) {
518 523
            pmc = alpha;
519 524
            sep = order.size();
520 525
          }
521 526
        }
522 527
      }
523 528

	
524 529
      if (static_cast<int>(order.size()) < _node_num) {
525 530
        _first_node = INVALID;
526 531
        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
527 532
          (*_cut_map)[n] = false;
528 533
        }
529 534
        for (int i = 0; i < static_cast<int>(order.size()); ++i) {
530 535
          typename Graph::Node n = order[i];
531 536
          while (n != INVALID) {
532 537
            (*_cut_map)[n] = true;
533 538
            n = (*_next_rep)[n];
534 539
          }
535 540
        }
536 541
        _min_cut = 0;
537 542
        return true;
538 543
      }
539 544

	
540 545
      if (pmc < _min_cut) {
541 546
        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
542 547
          (*_cut_map)[n] = false;
543 548
        }
544 549
        for (int i = 0; i < sep; ++i) {
545 550
          typename Graph::Node n = order[i];
546 551
          while (n != INVALID) {
547 552
            (*_cut_map)[n] = true;
548 553
            n = (*_next_rep)[n];
549 554
          }
550 555
        }
551 556
        _min_cut = pmc;
552 557
      }
553 558

	
554 559
      for (typename Graph::Node n = _first_node;
555 560
           n != INVALID; n = (*_nodes)[n].next) {
556 561
        bool merged = false;
557 562
        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
558 563
          if (!(_edges[a >> 1].cut < pmc)) {
559 564
            if (!merged) {
560 565
              for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
561 566
                (*_nodes)[_arcs[b].target].curr_arc = b;          
562 567
              }
563 568
              merged = true;
564 569
            }
565 570
            typename Graph::Node m = _arcs[a].target;
566 571
            int nb = 0;
567 572
            for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
568 573
              nb = _arcs[b].next;
569 574
              if ((b ^ a) == 1) continue;
570 575
              typename Graph::Node o = _arcs[b].target;
571 576
              int c = (*_nodes)[o].curr_arc; 
572 577
              if (c != -1 && _arcs[c ^ 1].target == n) {
573 578
                _edges[c >> 1].capacity += _edges[b >> 1].capacity;
574 579
                (*_nodes)[n].sum += _edges[b >> 1].capacity;
575 580
                if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
576 581
                  _edges[b >> 1].cut = _edges[c >> 1].cut;
577 582
                }
578 583
                if (_arcs[b ^ 1].prev != -1) {
579 584
                  _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
580 585
                } else {
581 586
                  (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
582 587
                }
583 588
                if (_arcs[b ^ 1].next != -1) {
584 589
                  _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
585 590
                }
586 591
              } else {
587 592
                if (_arcs[a].next != -1) {
588 593
                  _arcs[_arcs[a].next].prev = b;
589 594
                }
590 595
                _arcs[b].next = _arcs[a].next;
591 596
                _arcs[b].prev = a;
592 597
                _arcs[a].next = b;
593 598
                _arcs[b ^ 1].target = n;
594 599

	
595 600
                (*_nodes)[n].sum += _edges[b >> 1].capacity;
596 601
                (*_nodes)[o].curr_arc = b;
597 602
              }
598 603
            }
599 604

	
600 605
            if (_arcs[a].prev != -1) {
601 606
              _arcs[_arcs[a].prev].next = _arcs[a].next;
602 607
            } else {
603 608
              (*_nodes)[n].first_arc = _arcs[a].next;
604 609
            }            
605 610
            if (_arcs[a].next != -1) {
606 611
              _arcs[_arcs[a].next].prev = _arcs[a].prev;
607 612
            }
608 613

	
609 614
            (*_nodes)[n].sum -= _edges[a >> 1].capacity;
610 615
            (*_next_rep)[(*_nodes)[n].last_rep] = m;
611 616
            (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
612 617
            
613 618
            if ((*_nodes)[m].prev != INVALID) {
614 619
              (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
615 620
            } else{
616 621
              _first_node = (*_nodes)[m].next;
617 622
            }
618 623
            if ((*_nodes)[m].next != INVALID) {
619 624
              (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
620 625
            }
621 626
            --_node_num;
622 627
          }
623 628
        }
624 629
      }
625 630

	
626 631
      if (_node_num == 1) {
627 632
        _first_node = INVALID;
628 633
        return true;
629 634
      }
630 635

	
631 636
      return false;
632 637
    }
633 638

	
634 639
    /// \brief Executes the algorithm.
635 640
    ///
636 641
    /// Executes the algorithm.
637 642
    ///
638 643
    /// \pre init() must be called
639 644
    void start() {
640 645
      while (!processNextPhase()) {}
641 646
    }
642 647

	
643 648

	
644 649
    /// \brief Runs %NagamochiIbaraki algorithm.
645 650
    ///
646 651
    /// This method runs the %Min cut algorithm
647 652
    ///
648 653
    /// \note mc.run(s) is just a shortcut of the following code.
649 654
    ///\code
650 655
    ///  mc.init();
651 656
    ///  mc.start();
652 657
    ///\endcode
653 658
    void run() {
654 659
      init();
655 660
      start();
656 661
    }
657 662

	
658 663
    ///@}
659 664

	
660 665
    /// \name Query Functions
661 666
    ///
662 667
    /// The result of the %NagamochiIbaraki
663 668
    /// algorithm can be obtained using these functions.\n
664 669
    /// Before the use of these functions, either run() or start()
665 670
    /// must be called.
666 671

	
667 672
    ///@{
668 673

	
669 674
    /// \brief Returns the min cut value.
670 675
    ///
671 676
    /// Returns the min cut value if the algorithm finished.
672 677
    /// After the first processNextPhase() it is a value of a
673 678
    /// valid cut in the graph.
674 679
    Value minCutValue() const {
675 680
      return _min_cut;
676 681
    }
677 682

	
678 683
    /// \brief Returns a min cut in a NodeMap.
679 684
    ///
680 685
    /// It sets the nodes of one of the two partitions to true and
681 686
    /// the other partition to false.
682 687
    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
683 688
    /// \c bool (or convertible) value type.
684 689
    template <typename CutMap>
685 690
    Value minCutMap(CutMap& cutMap) const {
686 691
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
687 692
        cutMap.set(n, (*_cut_map)[n]);
688 693
      }
689 694
      return minCutValue();
690 695
    }
691 696

	
692 697
    ///@}
693 698

	
694 699
  };
695 700
}
696 701

	
697 702
#endif
0 comments (0 inline)