~ubuntu-branches/debian/stretch/cgal/stretch

« back to all changes in this revision

Viewing changes to include/CGAL/internal/auxiliary/graph.h

  • Committer: Package Import Robot
  • Author(s): Joachim Reichel
  • Date: 2014-04-05 10:56:43 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20140405105643-jgnrpu2thtx23zfs
Tags: 4.4-1
* New upstream release.
* Remove patches do-not-link-example-with-qt4-support-library.patch and
  fix_jet_fitting_3.patch (applied upstream).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2001  Yuri Boykov
 
2
// All rights reserved.
 
3
//
 
4
// This file is part of CGAL (www.cgal.org).
 
5
// You can redistribute it and/or modify it under the terms of the GNU
 
6
// General Public License as published by the Free Software Foundation,
 
7
// either version 3 of the License, or (at your option) any later version.
 
8
//
 
9
// Licensees holding a valid commercial license may use this file in
 
10
// accordance with the commercial license agreement provided with the software.
 
11
//
 
12
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
13
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
14
/*
 
15
###################################################################
 
16
#                                                                 #
 
17
#    MAXFLOW - software for computing mincut/maxflow in a graph   #
 
18
#                        Version 2.21                             #
 
19
#    http://www.cs.ucl.ac.uk/staff/V.Kolmogorov/software.html     #
 
20
#                                                                 #
 
21
#    Yuri Boykov (yuri@csd.uwo.ca)                                #
 
22
#    Vladimir Kolmogorov (v.kolmogorov@cs.ucl.ac.uk)              #
 
23
#    2001                                                         #
 
24
#                                                                 #
 
25
###################################################################
 
26
 
 
27
1. Introduction.
 
28
 
 
29
This software library implements the maxflow algorithm
 
30
described in
 
31
 
 
32
        An Experimental Comparison of Min-Cut/Max-Flow Algorithms
 
33
        for Energy Minimization in Vision.
 
34
        Yuri Boykov and Vladimir Kolmogorov.
 
35
        In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI),
 
36
        September 2004
 
37
 
 
38
This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov
 
39
at Siemens Corporate Research. To make it available for public use,
 
40
it was later reimplemented by Vladimir Kolmogorov based on open publications.
 
41
 
 
42
If you use this software for research purposes, you should cite
 
43
the aforementioned paper in any resulting publication.
 
44
 
 
45
Tested under windows, Visual C++ 6.0 compiler and unix (SunOS 5.8
 
46
and RedHat Linux 7.0, GNU c++ compiler).
 
47
 
 
48
##################################################################
 
49
 
 
50
2. Licence.
 
51
 
 
52
Copyright UCL Business PLC
 
53
 
 
54
This program is available under dual licence:
 
55
 
 
56
1) Under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
57
Note that any program that incorporates the code under this licence must, under the terms of the GNU GPL, be released under a licence compatible with the GPL. GNU GPL does not permit incorporating this program into proprietary programs. If you wish to do this, please see the alternative licence available below.
 
58
GNU General Public License can be found at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 
59
 
 
60
2) Proprietary Licence from UCL Business PLC.
 
61
To enable programers to include the MaxFlow software in a proprietary system (which is not allowed by the GNU GPL), this licence gives you the right to incorporate the software in your program and distribute under any licence of your choosing. The full terms of the licence and applicable fee, are available from the Licensors at: http://www.uclb-elicensing.com/optimisation_software/maxflow_computervision.html
 
62
 
 
63
##################################################################
 
64
 
 
65
3. Graph representation.
 
66
 
 
67
There are two versions of the algorithm using different
 
68
graph representations (adjacency list and forward star).
 
69
The former one uses more than twice as much memory as the
 
70
latter one but is 10-20% faster.
 
71
 
 
72
Memory allocation (assuming that all capacities are 'short' - 2 bytes):
 
73
 
 
74
                 |   Nodes    |   Arcs
 
75
------------------------------------------
 
76
Adjacency list   | *24 bytes  | *14 bytes
 
77
Forward star     | *28 bytes  |  6 bytes
 
78
 
 
79
(* means that often it should be rounded up to be a multiple of 4
 
80
- some compilers (e.g. Visual C++) seem to round up elements
 
81
of arrays unless the are structures containing only char[].)
 
82
 
 
83
Note that arcs are always added in pairs - in forward and reverse directions.
 
84
Arcs between nodes and terminals (the source and the sink) are
 
85
not stored as arcs, but rather as a part of nodes.
 
86
 
 
87
The assumption for the forward star representation is that
 
88
the maximum number of arcs per node (except the source
 
89
and the sink) is much less than ARC_BLOCK_SIZE (1024 by default).
 
90
 
 
91
Both versions have the same interface.
 
92
 
 
93
##################################################################
 
94
 
 
95
4. Example usage.
 
96
 
 
97
This section shows how to use the library to compute
 
98
a minimum cut on the following graph:
 
99
 
 
100
                        SOURCE
 
101
                       /       \
 
102
                     1/         \2
 
103
                     /      3    \
 
104
                   node0 -----> node1
 
105
                     |   <-----   |
 
106
                     |      4     |
 
107
                     \            /
 
108
                     5\          /6
 
109
                       \        /
 
110
                          SINK
 
111
 
 
112
///////////////////////////////////////////////////
 
113
 
 
114
#include <stdio.h>
 
115
#include "graph.h"
 
116
 
 
117
void main()
 
118
{
 
119
        Graph::node_id nodes[2];
 
120
        Graph *g = new Graph();
 
121
 
 
122
        nodes[0] = g -> add_node();
 
123
        nodes[1] = g -> add_node();
 
124
        g -> set_tweights(nodes[0], 1, 5);
 
125
        g -> set_tweights(nodes[1], 2, 6);
 
126
        g -> add_edge(nodes[0], nodes[1], 3, 4);
 
127
 
 
128
        Graph::flowtype flow = g -> maxflow();
 
129
 
 
130
        printf("Flow = %d\n", flow);
 
131
        printf("Minimum cut:\n");
 
132
        if (g->what_segment(nodes[0]) == Graph::SOURCE)
 
133
                printf("node0 is in the SOURCE set\n");
 
134
        else
 
135
                printf("node0 is in the SINK set\n");
 
136
        if (g->what_segment(nodes[1]) == Graph::SOURCE)
 
137
                printf("node1 is in the SOURCE set\n");
 
138
        else
 
139
                printf("node1 is in the SINK set\n");
 
140
 
 
141
        delete g;
 
142
}
 
143
 
 
144
///////////////////////////////////////////////////
 
145
*/
 
146
 
 
147
/* block.h */
 
148
/*
 
149
        Template classes Block and DBlock
 
150
        Implement adding and deleting items of the same type in blocks.
 
151
 
 
152
        If there there are many items then using Block or DBlock
 
153
        is more efficient than using 'new' and 'delete' both in terms
 
154
        of memory and time since
 
155
        (1) On some systems there is some minimum amount of memory
 
156
            that 'new' can allocate (e.g., 64), so if items are
 
157
            small that a lot of memory is wasted.
 
158
        (2) 'new' and 'delete' are designed for items of varying size.
 
159
            If all items has the same size, then an algorithm for
 
160
            adding and deleting can be made more efficient.
 
161
        (3) All Block and DBlock functions are inline, so there are
 
162
            no extra function calls.
 
163
 
 
164
        Differences between Block and DBlock:
 
165
        (1) DBlock allows both adding and deleting items,
 
166
            whereas Block allows only adding items.
 
167
        (2) Block has an additional operation of scanning
 
168
            items added so far (in the order in which they were added).
 
169
        (3) Block allows to allocate several consecutive
 
170
            items at a time, whereas DBlock can add only a single item.
 
171
 
 
172
        Note that no constructors or destructors are called for items.
 
173
 
 
174
        Example usage for items of type 'MyType':
 
175
 
 
176
        ///////////////////////////////////////////////////
 
177
        #include "block.h"
 
178
        #define BLOCK_SIZE 1024
 
179
        typedef struct { int a, b; } MyType;
 
180
        MyType *ptr, *array[10000];
 
181
 
 
182
        ...
 
183
 
 
184
        Block<MyType> *block = new Block<MyType>(BLOCK_SIZE);
 
185
 
 
186
        // adding items
 
187
        for (int i=0; i<sizeof(array); i++)
 
188
        {
 
189
                ptr = block -> New();
 
190
                ptr -> a = ptr -> b = rand();
 
191
        }
 
192
 
 
193
        // reading items
 
194
        for (ptr=block->ScanFirst(); ptr; ptr=block->ScanNext())
 
195
        {
 
196
                printf("%d %d\n", ptr->a, ptr->b);
 
197
        }
 
198
 
 
199
        delete block;
 
200
 
 
201
        ...
 
202
 
 
203
        DBlock<MyType> *dblock = new DBlock<MyType>(BLOCK_SIZE);
 
204
 
 
205
        // adding items
 
206
        for (int i=0; i<sizeof(array); i++)
 
207
        {
 
208
                array[i] = dblock -> New();
 
209
        }
 
210
 
 
211
        // deleting items
 
212
        for (int i=0; i<sizeof(array); i+=2)
 
213
        {
 
214
                dblock -> Delete(array[i]);
 
215
        }
 
216
 
 
217
        // adding items
 
218
        for (int i=0; i<sizeof(array); i++)
 
219
        {
 
220
                array[i] = dblock -> New();
 
221
        }
 
222
 
 
223
        delete dblock;
 
224
 
 
225
        ///////////////////////////////////////////////////
 
226
 
 
227
        Note that DBlock deletes items by marking them as
 
228
        empty (i.e., by adding them to the list of free items),
 
229
        so that this memory could be used for subsequently
 
230
        added items. Thus, at each moment the memory allocated
 
231
        is determined by the maximum number of items allocated
 
232
        simultaneously at earlier moments. All memory is
 
233
        deallocated only when the destructor is called.
 
234
*/
 
235
 
 
236
#ifndef __BLOCK_H__
 
237
#define __BLOCK_H__
 
238
 
 
239
#include <stdlib.h>
 
240
 
 
241
/***********************************************************************/
 
242
/***********************************************************************/
 
243
/***********************************************************************/
 
244
 
 
245
template <class Type> class Block
 
246
{
 
247
public:
 
248
  /* Constructor. Arguments are the block size and
 
249
     (optionally) the pointer to the function which
 
250
     will be called if allocation failed; the message
 
251
     passed to this function is "Not enough memory!" */
 
252
  Block(int size, void (*err_function)(const char *) = NULL) {
 
253
    first = last = NULL;
 
254
    block_size = size;
 
255
    error_function = err_function;
 
256
  }
 
257
 
 
258
  /* Destructor. Deallocates all items added so far */
 
259
  ~Block() {
 
260
    while (first) {
 
261
      block *next = first -> next;
 
262
      delete[] ((char*)first);
 
263
      first = next;
 
264
    }
 
265
  }
 
266
 
 
267
  /* Allocates 'num' consecutive items; returns pointer
 
268
     to the first item. 'num' cannot be greater than the
 
269
     block size since items must fit in one block */
 
270
  Type *New(int num = 1) {
 
271
    Type *t;
 
272
 
 
273
    if (!last || last->current + num > last->last) {
 
274
      if (last && last->next) last = last -> next;
 
275
      else {
 
276
        block *next = (block *) new char [sizeof(block) + (block_size-1)*sizeof(Type)];
 
277
        if (!next) {
 
278
          if (error_function) (*error_function)("Not enough memory!");
 
279
          exit(1);
 
280
        }
 
281
        if (last) last -> next = next;
 
282
        else first = next;
 
283
        last = next;
 
284
        last -> current = & ( last -> data[0] );
 
285
        last -> last = last -> current + block_size;
 
286
        last -> next = NULL;
 
287
      }
 
288
    }
 
289
 
 
290
    t = last -> current;
 
291
    last -> current += num;
 
292
    return t;
 
293
  }
 
294
 
 
295
  /* Returns the first item (or NULL, if no items were added) */
 
296
  Type *ScanFirst() {
 
297
    for (scan_current_block=first; scan_current_block;
 
298
         scan_current_block = scan_current_block->next) {
 
299
      scan_current_data = & ( scan_current_block -> data[0] );
 
300
      if (scan_current_data < scan_current_block -> current) return scan_current_data
 
301
            ++;
 
302
    }
 
303
    return NULL;
 
304
  }
 
305
 
 
306
  /* Returns the next item (or NULL, if all items have been read)
 
307
     Can be called only if previous ScanFirst() or ScanNext()
 
308
     call returned not NULL. */
 
309
  Type *ScanNext() {
 
310
    while (scan_current_data >= scan_current_block -> current) {
 
311
      scan_current_block = scan_current_block -> next;
 
312
      if (!scan_current_block) return NULL;
 
313
      scan_current_data = & ( scan_current_block -> data[0] );
 
314
    }
 
315
    return scan_current_data ++;
 
316
  }
 
317
 
 
318
  /* Marks all elements as empty */
 
319
  void Reset() {
 
320
    block *b;
 
321
    if (!first) return;
 
322
    for (b=first; ; b=b->next) {
 
323
      b -> current = & ( b -> data[0] );
 
324
      if (b == last) break;
 
325
    }
 
326
    last = first;
 
327
  }
 
328
 
 
329
  /***********************************************************************/
 
330
 
 
331
private:
 
332
 
 
333
  typedef struct block_st {
 
334
    Type                                        *current, *last;
 
335
    struct block_st                     *next;
 
336
    Type                                        data[1];
 
337
  } block;
 
338
 
 
339
  int           block_size;
 
340
  block *first;
 
341
  block *last;
 
342
 
 
343
  block *scan_current_block;
 
344
  Type  *scan_current_data;
 
345
 
 
346
  void  (*error_function)(const char *);
 
347
};
 
348
 
 
349
/***********************************************************************/
 
350
/***********************************************************************/
 
351
/***********************************************************************/
 
352
 
 
353
template <class Type> class DBlock
 
354
{
 
355
public:
 
356
  /* Constructor. Arguments are the block size and
 
357
     (optionally) the pointer to the function which
 
358
     will be called if allocation failed; the message
 
359
     passed to this function is "Not enough memory!" */
 
360
  DBlock(int size, void (*err_function)(const char *) = NULL) {
 
361
    first = NULL;
 
362
    first_free = NULL;
 
363
    block_size = size;
 
364
    error_function = err_function;
 
365
  }
 
366
 
 
367
  /* Destructor. Deallocates all items added so far */
 
368
  ~DBlock() {
 
369
    while (first) {
 
370
      block *next = first -> next;
 
371
      delete[] ((char*)first);
 
372
      first = next;
 
373
    }
 
374
  }
 
375
 
 
376
  /* Allocates one item */
 
377
  Type *New() {
 
378
    block_item *item;
 
379
 
 
380
    if (!first_free) {
 
381
      block *next = first;
 
382
      first = (block *) new char [sizeof(block) + (block_size-1)*sizeof(block_item)];
 
383
      if (!first) {
 
384
        if (error_function) (*error_function)("Not enough memory!");
 
385
        exit(1);
 
386
      }
 
387
      first_free = & (first -> data[0] );
 
388
      for (item=first_free; item<first_free+block_size-1; item++)
 
389
        item -> next_free = item + 1;
 
390
      item -> next_free = NULL;
 
391
      first -> next = next;
 
392
    }
 
393
 
 
394
    item = first_free;
 
395
    first_free = item -> next_free;
 
396
    return (Type *) item;
 
397
  }
 
398
 
 
399
  /* Deletes an item allocated previously */
 
400
  void Delete(Type *t) {
 
401
    ((block_item *) t) -> next_free = first_free;
 
402
    first_free = (block_item *) t;
 
403
  }
 
404
 
 
405
  /***********************************************************************/
 
406
 
 
407
private:
 
408
 
 
409
  typedef union block_item_st {
 
410
    Type                        t;
 
411
    block_item_st       *next_free;
 
412
  } block_item;
 
413
 
 
414
  typedef struct block_st {
 
415
    struct block_st                     *next;
 
416
    block_item                          data[1];
 
417
  } block;
 
418
 
 
419
  int                   block_size;
 
420
  block         *first;
 
421
  block_item    *first_free;
 
422
 
 
423
  void  (*error_function)(const char *);
 
424
};
 
425
 
 
426
 
 
427
#endif
 
428
 
 
429
 
 
430
 
 
431
/* graph.h */
 
432
/*
 
433
        This software library implements the maxflow algorithm
 
434
        described in
 
435
 
 
436
                An Experimental Comparison of Min-Cut/Max-Flow Algorithms
 
437
                for Energy Minimization in Vision.
 
438
                Yuri Boykov and Vladimir Kolmogorov.
 
439
                In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI),
 
440
                September 2004
 
441
 
 
442
        This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov
 
443
        at Siemens Corporate Research. To make it available for public use,
 
444
        it was later reimplemented by Vladimir Kolmogorov based on open publications.
 
445
 
 
446
        If you use this software for research purposes, you should cite
 
447
        the aforementioned paper in any resulting publication.
 
448
 
 
449
        ----------------------------------------------------------------
 
450
 
 
451
        For description, license, example usage, discussion of graph representation     and memory usage see README.TXT.
 
452
*/
 
453
 
 
454
#ifndef __GRAPH_H__
 
455
#define __GRAPH_H__
 
456
 
 
457
//#include "block.h"
 
458
#include <stdio.h>
 
459
/*
 
460
        Nodes, arcs and pointers to nodes are
 
461
        added in blocks for memory and time efficiency.
 
462
        Below are numbers of items in blocks
 
463
*/
 
464
#define NODE_BLOCK_SIZE 512
 
465
#define ARC_BLOCK_SIZE 1024
 
466
#define NODEPTR_BLOCK_SIZE 128
 
467
 
 
468
template <std::size_t size>
 
469
struct Int_to_ptr;
 
470
 
 
471
template<> struct Int_to_ptr<sizeof(int)> {
 
472
  typedef int type;
 
473
};
 
474
#if INT_MAX != LONG_MAX
 
475
template<> struct Int_to_ptr<sizeof(long)> {
 
476
  typedef long type;
 
477
};
 
478
#else
 
479
template<> struct Int_to_ptr<sizeof(long long)> {
 
480
  typedef long long type;
 
481
};
 
482
#endif
 
483
 
 
484
 
 
485
class Graph
 
486
{
 
487
public:
 
488
  typedef enum {
 
489
    SOURCE      = 0,
 
490
    SINK        = 1
 
491
  } termtype; /* terminals */
 
492
 
 
493
  /* Type of edge weights.
 
494
     Can be changed to char, int, float, double, ... */
 
495
  typedef double captype;
 
496
  /* Type of total flow */
 
497
  typedef double flowtype;
 
498
 
 
499
  typedef void * node_id;
 
500
 
 
501
  /* interface functions */
 
502
 
 
503
  /* Constructor. Optional argument is the pointer to the
 
504
     function which will be called if an error occurs;
 
505
     an error message is passed to this function. If this
 
506
     argument is omitted, exit(1) will be called. */
 
507
  Graph(void (*err_function)(const char *) = NULL);
 
508
 
 
509
  /* Destructor */
 
510
  ~Graph();
 
511
 
 
512
  /* Adds a node to the graph */
 
513
  node_id add_node();
 
514
 
 
515
  /* Adds a bidirectional edge between 'from' and 'to'
 
516
     with the weights 'cap' and 'rev_cap' */
 
517
  void add_edge(node_id from, node_id to, captype cap, captype rev_cap);
 
518
 
 
519
  /* Sets the weights of the edges 'SOURCE->i' and 'i->SINK'
 
520
     Can be called at most once for each node before any call to 'add_tweights'.
 
521
     Weights can be negative */
 
522
  void set_tweights(node_id i, captype cap_source, captype cap_sink);
 
523
 
 
524
  /* Adds new edges 'SOURCE->i' and 'i->SINK' with corresponding weights
 
525
     Can be called multiple times for each node.
 
526
     Weights can be negative */
 
527
  void add_tweights(node_id i, captype cap_source, captype cap_sink);
 
528
 
 
529
  /* After the maxflow is computed, this function returns to which
 
530
     segment the node 'i' belongs (Graph::SOURCE or Graph::SINK) */
 
531
  termtype what_segment(node_id i);
 
532
 
 
533
  /* Computes the maxflow. Can be called only once. */
 
534
  flowtype maxflow();
 
535
 
 
536
  /***********************************************************************/
 
537
  /***********************************************************************/
 
538
  /***********************************************************************/
 
539
 
 
540
private:
 
541
  /* internal variables and functions */
 
542
 
 
543
  struct arc_forward_st;
 
544
  struct arc_reverse_st;
 
545
 
 
546
  typedef Int_to_ptr< sizeof(void*) >::type INTEGER;
 
547
#define IS_ODD(a) ((INTEGER)(a) & 1)
 
548
#define MAKE_ODD(a)  ((arc_forward *) ((INTEGER)(a) | 1))
 
549
#define MAKE_EVEN(a) ((arc_forward *) ((INTEGER)(a) & (~1)))
 
550
#define MAKE_ODD_REV(a)  ((arc_reverse *) ((INTEGER)(a) | 1))
 
551
#define MAKE_EVEN_REV(a) ((arc_reverse *) ((INTEGER)(a) & (~1)))
 
552
#define POINTER_TO_INTEGER(ptr) ((INTEGER) ptr)
 
553
 
 
554
 
 
555
 
 
556
  /* node structure */
 
557
  typedef struct node_st {
 
558
    /*
 
559
        Usually i->first_out is the first outgoing
 
560
        arc, and (i+1)->first_out-1 is the last outgoing arc.
 
561
        However, it is not always possible, since
 
562
        arcs are allocated in blocks, so arcs corresponding
 
563
        to two consecutive nodes may be in different blocks.
 
564
 
 
565
        If outgoing arcs for i are last in the arc block,
 
566
        then a different mechanism is used. i->first_out
 
567
        is odd in this case; the first outgoing arc
 
568
        is (a+1), and the last outgoing arc is
 
569
        ((arc_forward *)(a->shift))-1, where
 
570
        a = (arc_forward *) (((char *)(i->first_out)) + 1);
 
571
 
 
572
        Similar mechanism is used for incoming arcs.
 
573
    */
 
574
    arc_forward_st      *first_out;     /* first outcoming arc */
 
575
    arc_reverse_st      *first_in;      /* first incoming arc */
 
576
 
 
577
    arc_forward_st      *parent;        /* describes node's parent
 
578
                                                                           if IS_ODD(parent) then MAKE_EVEN(parent) points to 'arc_reverse',
 
579
                                                                           otherwise parent points to 'arc_forward' */
 
580
 
 
581
    node_st                     *next;          /* pointer to the next active node
 
582
                                                                           (or to itself if it is the last node in the list) */
 
583
 
 
584
    int                         TS;                     /* timestamp showing when DIST was computed */
 
585
    int                         DIST;           /* distance to the terminal */
 
586
    short                       is_sink;        /* flag showing whether the node is in the source or in the sink tree */
 
587
 
 
588
    captype                     tr_cap;         /* if tr_cap > 0 then tr_cap is residual capacity of the arc SOURCE->node
 
589
                                                                           otherwise         -tr_cap is residual capacity of the arc node->SINK */
 
590
  } node;
 
591
 
 
592
  /* arc structures */
 
593
#define NEIGHBOR_NODE(i, shift) ((node *) ((char *)(i) + (shift)))
 
594
#define NEIGHBOR_NODE_REV(i, shift) ((node *) ((char *)(i) - (shift)))
 
595
  typedef struct arc_forward_st {
 
596
    INTEGER                     shift;          /* node_to = NEIGHBOR_NODE(node_from, shift) */
 
597
    captype                     r_cap;          /* residual capacity */
 
598
    captype                     r_rev_cap;      /* residual capacity of the reverse arc*/
 
599
  } arc_forward;
 
600
 
 
601
  typedef struct arc_reverse_st {
 
602
    arc_forward         *sister;        /* reverse arc */
 
603
  } arc_reverse;
 
604
 
 
605
  /* 'pointer to node' structure */
 
606
  typedef struct nodeptr_st {
 
607
    node_st                     *ptr;
 
608
    nodeptr_st          *next;
 
609
  } nodeptr;
 
610
 
 
611
  typedef struct node_block_st {
 
612
    node                                        *current;
 
613
    struct node_block_st        *next;
 
614
    node                                        nodes[NODE_BLOCK_SIZE];
 
615
  } node_block;
 
616
 
 
617
#define last_node LAST_NODE.LAST_NODE
 
618
 
 
619
  typedef struct arc_for_block_st {
 
620
    char                                        *start;         /* the actual start address of this block.
 
621
                                                                                           May be different from 'this' since 'this'
 
622
                                                                                           must be at an even address. */
 
623
    arc_forward                         *current;
 
624
    struct arc_for_block_st     *next;
 
625
    arc_forward
 
626
    arcs_for[ARC_BLOCK_SIZE]; /* all arcs must be at even addresses */
 
627
    union {
 
628
      arc_forward                       dummy;
 
629
      node                              *LAST_NODE;     /* used in graph consruction */
 
630
    }                                           LAST_NODE;
 
631
  } arc_for_block;
 
632
 
 
633
  typedef struct arc_rev_block_st {
 
634
    char                                        *start;         /* the actual start address of this block.
 
635
                                                                                           May be different from 'this' since 'this'
 
636
                                                                                           must be at an even address. */
 
637
    arc_reverse                         *current;
 
638
    struct arc_rev_block_st     *next;
 
639
    arc_reverse
 
640
    arcs_rev[ARC_BLOCK_SIZE]; /* all arcs must be at even addresses */
 
641
    union {
 
642
      arc_reverse                       dummy;
 
643
      node                              *LAST_NODE;     /* used in graph consruction */
 
644
    }                                           LAST_NODE;
 
645
  } arc_rev_block;
 
646
 
 
647
  node_block                    *node_block_first;
 
648
  arc_for_block         *arc_for_block_first;
 
649
  arc_rev_block         *arc_rev_block_first;
 
650
  DBlock<nodeptr>               *nodeptr_block;
 
651
 
 
652
  void  (*error_function)(const char
 
653
                          *);   /* this function is called if a error occurs,
 
654
                                                                                   with a corresponding error message
 
655
                                                                                   (or exit(1) is called if it's NULL) */
 
656
 
 
657
  flowtype                      flow;           /* total flow */
 
658
 
 
659
  /***********************************************************************/
 
660
 
 
661
  node                          *queue_first[2], *queue_last[2];        /* list of active nodes */
 
662
  nodeptr                               *orphan_first, *orphan_last;            /* list of pointers to orphans */
 
663
  int                                   TIME;                                                           /* monotonically increasing global counter */
 
664
 
 
665
  /***********************************************************************/
 
666
 
 
667
  /* functions for processing active list */
 
668
  void set_active(node *i);
 
669
  node *next_active();
 
670
 
 
671
  void prepare_graph();
 
672
  void maxflow_init();
 
673
  void augment(node *s_start, node *t_start, captype *cap_middle,
 
674
               captype *rev_cap_middle);
 
675
  void process_source_orphan(node *i);
 
676
  void process_sink_orphan(node *i);
 
677
};
 
678
/* graph.cpp */
 
679
 
 
680
 
 
681
//#include <stdio.h>
 
682
//#include "graph.h"
 
683
 
 
684
inline Graph::Graph(void (*err_function)(const char *))
 
685
{
 
686
  error_function = err_function;
 
687
  node_block_first = NULL;
 
688
  arc_for_block_first = NULL;
 
689
  arc_rev_block_first = NULL;
 
690
  flow = 0;
 
691
}
 
692
 
 
693
inline Graph::~Graph()
 
694
{
 
695
  while (node_block_first) {
 
696
    node_block *next = node_block_first -> next;
 
697
    delete node_block_first;
 
698
    node_block_first = next;
 
699
  }
 
700
 
 
701
  while (arc_for_block_first) {
 
702
    arc_for_block *next = arc_for_block_first -> next;
 
703
    delete[] arc_for_block_first -> start;
 
704
    arc_for_block_first = next;
 
705
  }
 
706
 
 
707
  while (arc_rev_block_first) {
 
708
    arc_rev_block *next = arc_rev_block_first -> next;
 
709
    delete[] arc_rev_block_first -> start;
 
710
    arc_rev_block_first = next;
 
711
  }
 
712
}
 
713
 
 
714
inline Graph::node_id Graph::add_node()
 
715
{
 
716
  node *i;
 
717
 
 
718
  if (!node_block_first
 
719
      || node_block_first->current+1 > &node_block_first->nodes[NODE_BLOCK_SIZE-1]) {
 
720
    node_block *next = node_block_first;
 
721
    node_block_first = (node_block *) new node_block;
 
722
    if (!node_block_first) {
 
723
      if (error_function) (*error_function)("Not enough memory!");
 
724
      exit(1);
 
725
    }
 
726
    node_block_first -> current = & ( node_block_first -> nodes[0] );
 
727
    node_block_first -> next = next;
 
728
  }
 
729
 
 
730
  i = node_block_first -> current ++;
 
731
  i -> first_out = (arc_forward *) 0;
 
732
  i -> first_in = (arc_reverse *) 0;
 
733
 
 
734
  i -> tr_cap = 0;
 
735
 
 
736
  return (node_id) i;
 
737
}
 
738
 
 
739
inline void Graph::add_edge(node_id from, node_id to, captype cap,
 
740
                            captype rev_cap)
 
741
{
 
742
  arc_forward *a_for;
 
743
  arc_reverse *a_rev;
 
744
 
 
745
  if (!arc_for_block_first
 
746
      || arc_for_block_first->current+1 >
 
747
      &arc_for_block_first->arcs_for[ARC_BLOCK_SIZE]) {
 
748
    arc_for_block *next = arc_for_block_first;
 
749
    char *ptr = new char[sizeof(arc_for_block)+1];
 
750
    if (!ptr) {
 
751
      if (error_function) (*error_function)("Not enough memory!");
 
752
      exit(1);
 
753
    }
 
754
    if (IS_ODD(ptr)) arc_for_block_first = (arc_for_block *) (ptr + 1);
 
755
    else              arc_for_block_first = (arc_for_block *) ptr;
 
756
    arc_for_block_first -> start = ptr;
 
757
    arc_for_block_first -> current = & ( arc_for_block_first -> arcs_for[0] );
 
758
    arc_for_block_first -> next = next;
 
759
  }
 
760
 
 
761
  if (!arc_rev_block_first
 
762
      || arc_rev_block_first->current+1 >
 
763
      &arc_rev_block_first->arcs_rev[ARC_BLOCK_SIZE]) {
 
764
    arc_rev_block *next = arc_rev_block_first;
 
765
    char *ptr = new char[sizeof(arc_rev_block)+1];
 
766
    if (!ptr) {
 
767
      if (error_function) (*error_function)("Not enough memory!");
 
768
      exit(1);
 
769
    }
 
770
    if (IS_ODD(ptr)) arc_rev_block_first = (arc_rev_block *) (ptr + 1);
 
771
    else              arc_rev_block_first = (arc_rev_block *) ptr;
 
772
    arc_rev_block_first -> start = ptr;
 
773
    arc_rev_block_first -> current = & ( arc_rev_block_first -> arcs_rev[0] );
 
774
    arc_rev_block_first -> next = next;
 
775
  }
 
776
 
 
777
  a_for = arc_for_block_first -> current ++;
 
778
  a_rev = arc_rev_block_first -> current ++;
 
779
 
 
780
  a_rev -> sister = (arc_forward *) from;
 
781
  a_for -> shift  = POINTER_TO_INTEGER(to);
 
782
  a_for -> r_cap = cap;
 
783
  a_for -> r_rev_cap = rev_cap;
 
784
 
 
785
  ((node *)from) -> first_out =
 
786
    (arc_forward *) (POINTER_TO_INTEGER(((node *)from) -> first_out) + 1);
 
787
  ((node *)to) -> first_in =
 
788
    (arc_reverse *) (POINTER_TO_INTEGER(((node *)to) -> first_in) + 1);
 
789
}
 
790
 
 
791
inline void Graph::set_tweights(node_id i, captype cap_source, captype cap_sink)
 
792
{
 
793
  flow += (cap_source < cap_sink) ? cap_source : cap_sink;
 
794
  ((node*)i) -> tr_cap = cap_source - cap_sink;
 
795
}
 
796
 
 
797
inline void Graph::add_tweights(node_id i, captype cap_source, captype cap_sink)
 
798
{
 
799
  register captype delta = ((node*)i) -> tr_cap;
 
800
  if (delta > 0) cap_source += delta;
 
801
  else           cap_sink   -= delta;
 
802
  flow += (cap_source < cap_sink) ? cap_source : cap_sink;
 
803
  ((node*)i) -> tr_cap = cap_source - cap_sink;
 
804
}
 
805
 
 
806
/*
 
807
        Converts arcs added by 'add_edge()' calls
 
808
        to a forward star graph representation.
 
809
 
 
810
        Linear time algorithm.
 
811
        No or little additional memory is allocated
 
812
        during this process
 
813
        (it may be necessary to allocate additional
 
814
        arc blocks, since arcs corresponding to the
 
815
        same node must be contiguous, i.e. be in one
 
816
        arc block.)
 
817
*/
 
818
inline void Graph::prepare_graph()
 
819
{
 
820
  node *i;
 
821
  arc_for_block *ab_for, *ab_for_first;
 
822
  arc_rev_block *ab_rev, *ab_rev_first, *ab_rev_scan;
 
823
  arc_forward *a_for;
 
824
  arc_reverse *a_rev, *a_rev_scan, *a_rev_tmp=new arc_reverse;
 
825
  node_block *nb;
 
826
  bool for_flag = false, rev_flag = false;
 
827
  INTEGER k;
 
828
 
 
829
  if (!arc_rev_block_first) {
 
830
    node_id from = add_node(), to = add_node();
 
831
    add_edge(from, to, 1, 0);
 
832
  }
 
833
 
 
834
  /* FIRST STAGE */
 
835
  a_rev_tmp->sister = NULL;
 
836
  for (a_rev=arc_rev_block_first->current;
 
837
       a_rev<&arc_rev_block_first->arcs_rev[ARC_BLOCK_SIZE]; a_rev++) {
 
838
    a_rev -> sister = NULL;
 
839
  }
 
840
 
 
841
  ab_for = ab_for_first = arc_for_block_first;
 
842
  ab_rev = ab_rev_first = ab_rev_scan = arc_rev_block_first;
 
843
  a_for = &ab_for->arcs_for[0];
 
844
  a_rev = a_rev_scan = &ab_rev->arcs_rev[0];
 
845
 
 
846
  for (nb=node_block_first; nb; nb=nb->next) {
 
847
    for (i=&nb->nodes[0]; i<nb->current; i++) {
 
848
      /* outgoing arcs */
 
849
      k = POINTER_TO_INTEGER(i -> first_out);
 
850
      if (a_for + k > &ab_for->arcs_for[ARC_BLOCK_SIZE]) {
 
851
        if (k > ARC_BLOCK_SIZE) {
 
852
          if (error_function) (*error_function)("# of arcs per node exceeds block size!");
 
853
          exit(1);
 
854
        }
 
855
        if (for_flag) ab_for = NULL;
 
856
        else          {
 
857
          ab_for = ab_for -> next;
 
858
          ab_rev_scan = ab_rev_scan -> next;
 
859
        }
 
860
        if (ab_for == NULL) {
 
861
          arc_for_block *next = arc_for_block_first;
 
862
          char *ptr = new char[sizeof(arc_for_block)+1];
 
863
          if (!ptr) {
 
864
            if (error_function) (*error_function)("Not enough memory!");
 
865
            exit(1);
 
866
          }
 
867
          if (IS_ODD(ptr)) arc_for_block_first = (arc_for_block *) (ptr + 1);
 
868
          else              arc_for_block_first = (arc_for_block *) ptr;
 
869
          arc_for_block_first -> start = ptr;
 
870
          arc_for_block_first -> current = & ( arc_for_block_first -> arcs_for[0] );
 
871
          arc_for_block_first -> next = next;
 
872
          ab_for = arc_for_block_first;
 
873
          for_flag = true;
 
874
        } else a_rev_scan = &ab_rev_scan->arcs_rev[0];
 
875
        a_for = &ab_for->arcs_for[0];
 
876
      }
 
877
      if (ab_rev_scan) {
 
878
        a_rev_scan += k;
 
879
        i -> parent = (arc_forward *) a_rev_scan;
 
880
      } else i -> parent = (arc_forward *) a_rev_tmp;
 
881
      a_for += k;
 
882
      i -> first_out = a_for;
 
883
      ab_for -> last_node = i;
 
884
 
 
885
      /* incoming arcs */
 
886
      k = POINTER_TO_INTEGER(i -> first_in);
 
887
      if (a_rev + k > &ab_rev->arcs_rev[ARC_BLOCK_SIZE]) {
 
888
        if (k > ARC_BLOCK_SIZE) {
 
889
          if (error_function) (*error_function)("# of arcs per node exceeds block size!");
 
890
          exit(1);
 
891
        }
 
892
        if (rev_flag) ab_rev = NULL;
 
893
        else          ab_rev = ab_rev -> next;
 
894
        if (ab_rev == NULL) {
 
895
          arc_rev_block *next = arc_rev_block_first;
 
896
          char *ptr = new char[sizeof(arc_rev_block)+1];
 
897
          if (!ptr) {
 
898
            if (error_function) (*error_function)("Not enough memory!");
 
899
            exit(1);
 
900
          }
 
901
          if (IS_ODD(ptr)) arc_rev_block_first = (arc_rev_block *) (ptr + 1);
 
902
          else              arc_rev_block_first = (arc_rev_block *) ptr;
 
903
          arc_rev_block_first -> start = ptr;
 
904
          arc_rev_block_first -> current = & ( arc_rev_block_first -> arcs_rev[0] );
 
905
          arc_rev_block_first -> next = next;
 
906
          ab_rev = arc_rev_block_first;
 
907
          rev_flag = true;
 
908
        }
 
909
        a_rev = &ab_rev->arcs_rev[0];
 
910
      }
 
911
      a_rev += k;
 
912
      i -> first_in = a_rev;
 
913
      ab_rev -> last_node = i;
 
914
    }
 
915
    /* i is the last node in block */
 
916
    i -> first_out = a_for;
 
917
    i -> first_in  = a_rev;
 
918
  }
 
919
 
 
920
  /* SECOND STAGE */
 
921
  for (ab_for=arc_for_block_first; ab_for; ab_for=ab_for->next) {
 
922
    ab_for -> current = ab_for -> last_node -> first_out;
 
923
  }
 
924
 
 
925
  for ( ab_for=ab_for_first, ab_rev=ab_rev_first;
 
926
        ab_for;
 
927
        ab_for=ab_for->next, ab_rev=ab_rev->next )
 
928
    for ( a_for=&ab_for->arcs_for[0], a_rev=&ab_rev->arcs_rev[0];
 
929
          a_for<&ab_for->arcs_for[ARC_BLOCK_SIZE];
 
930
          a_for++, a_rev++ ) {
 
931
      arc_forward *af;
 
932
      arc_reverse *ar;
 
933
      node *from;
 
934
      INTEGER shift = 0, shift_new;
 
935
      captype r_cap=0, r_rev_cap=0, r_cap_new, r_rev_cap_new;
 
936
 
 
937
      if (!(from=(node *)(a_rev->sister))) continue;
 
938
      af = a_for;
 
939
      ar = a_rev;
 
940
 
 
941
      do {
 
942
        ar -> sister = NULL;
 
943
 
 
944
        shift_new = ((char *)(af->shift)) - (char *)from;
 
945
        r_cap_new = af -> r_cap;
 
946
        r_rev_cap_new = af -> r_rev_cap;
 
947
        if (shift) {
 
948
          af -> shift = shift;
 
949
          af -> r_cap = r_cap;
 
950
          af -> r_rev_cap = r_rev_cap;
 
951
        }
 
952
        shift = shift_new;
 
953
        r_cap = r_cap_new;
 
954
        r_rev_cap = r_rev_cap_new;
 
955
 
 
956
        af = -- from -> first_out;
 
957
        if ((arc_reverse *)(from->parent) != a_rev_tmp) {
 
958
          from -> parent = (arc_forward *)(((arc_reverse *)(from -> parent)) - 1);
 
959
          ar = (arc_reverse *)(from -> parent);
 
960
        }
 
961
      } while ( (from=(node *)(ar->sister)) );
 
962
 
 
963
      af -> shift = shift;
 
964
      af -> r_cap = r_cap;
 
965
      af -> r_rev_cap = r_rev_cap;
 
966
    }
 
967
 
 
968
  for (ab_for=arc_for_block_first; ab_for; ab_for=ab_for->next) {
 
969
    i = ab_for -> last_node;
 
970
    a_for = i -> first_out;
 
971
    ab_for -> current -> shift     = a_for -> shift;
 
972
    ab_for -> current -> r_cap     = a_for -> r_cap;
 
973
    ab_for -> current -> r_rev_cap = a_for -> r_rev_cap;
 
974
    a_for -> shift = POINTER_TO_INTEGER(ab_for -> current + 1);
 
975
    i -> first_out = (arc_forward *) (((char *)a_for) - 1);
 
976
  }
 
977
 
 
978
  /* THIRD STAGE */
 
979
  for (ab_rev=arc_rev_block_first; ab_rev; ab_rev=ab_rev->next) {
 
980
    ab_rev -> current = ab_rev -> last_node -> first_in;
 
981
  }
 
982
 
 
983
  for (nb=node_block_first; nb; nb=nb->next)
 
984
    for (i=&nb->nodes[0]; i<nb->current; i++) {
 
985
      arc_forward *a_for_first, *a_for_last;
 
986
 
 
987
      a_for_first = i -> first_out;
 
988
      if (IS_ODD(a_for_first)) {
 
989
        a_for_first = (arc_forward *) (((char *)a_for_first) + 1);
 
990
        a_for_last = (arc_forward *) ((a_for_first ++) -> shift);
 
991
      } else a_for_last = (i + 1) -> first_out;
 
992
 
 
993
      for (a_for=a_for_first; a_for<a_for_last; a_for++) {
 
994
        node *to = NEIGHBOR_NODE(i, a_for -> shift);
 
995
        a_rev = -- to -> first_in;
 
996
        a_rev -> sister = a_for;
 
997
      }
 
998
    }
 
999
 
 
1000
  for (ab_rev=arc_rev_block_first; ab_rev; ab_rev=ab_rev->next) {
 
1001
    i = ab_rev -> last_node;
 
1002
    a_rev = i -> first_in;
 
1003
    ab_rev -> current -> sister = a_rev -> sister;
 
1004
    a_rev -> sister = (arc_forward *) (ab_rev -> current + 1);
 
1005
    i -> first_in = (arc_reverse *) (((char *)a_rev) - 1);
 
1006
  }
 
1007
  delete a_rev_tmp;
 
1008
}
 
1009
 
 
1010
/* maxflow.cpp */
 
1011
 
 
1012
//#include <stdio.h>
 
1013
//#include "graph.h"
 
1014
 
 
1015
/*
 
1016
        special constants for node->parent
 
1017
*/
 
1018
#define TERMINAL ( (arc_forward *) 1 )          /* to terminal */
 
1019
#define ORPHAN   ( (arc_forward *) 2 )          /* orphan */
 
1020
 
 
1021
#define INFINITE_D 1000000000           /* infinite distance to the terminal */
 
1022
 
 
1023
/***********************************************************************/
 
1024
 
 
1025
/*
 
1026
        Functions for processing active list.
 
1027
        i->next points to the next node in the list
 
1028
        (or to i, if i is the last node in the list).
 
1029
        If i->next is NULL iff i is not in the list.
 
1030
 
 
1031
        There are two queues. Active nodes are added
 
1032
        to the end of the second queue and read from
 
1033
        the front of the first queue. If the first queue
 
1034
        is empty, it is replaced by the second queue
 
1035
        (and the second queue becomes empty).
 
1036
*/
 
1037
 
 
1038
inline void Graph::set_active(node *i)
 
1039
{
 
1040
  if (!i->next) {
 
1041
    /* it's not in the list yet */
 
1042
    if (queue_last[1]) queue_last[1] -> next = i;
 
1043
    else               queue_first[1]        = i;
 
1044
    queue_last[1] = i;
 
1045
    i -> next = i;
 
1046
  }
 
1047
}
 
1048
 
 
1049
/*
 
1050
        Returns the next active node.
 
1051
        If it is connected to the sink, it stays in the list,
 
1052
        otherwise it is removed from the list
 
1053
*/
 
1054
inline Graph::node * Graph::next_active()
 
1055
{
 
1056
  node *i;
 
1057
 
 
1058
  while ( 1 ) {
 
1059
    if (!(i=queue_first[0])) {
 
1060
      queue_first[0] = i = queue_first[1];
 
1061
      queue_last[0]  = queue_last[1];
 
1062
      queue_first[1] = NULL;
 
1063
      queue_last[1]  = NULL;
 
1064
      if (!i) return NULL;
 
1065
    }
 
1066
 
 
1067
    /* remove it from the active list */
 
1068
    if (i->next == i) queue_first[0] = queue_last[0] = NULL;
 
1069
    else              queue_first[0] = i -> next;
 
1070
    i -> next = NULL;
 
1071
 
 
1072
    /* a node in the list is active iff it has a parent */
 
1073
    if (i->parent) return i;
 
1074
  }
 
1075
}
 
1076
 
 
1077
/***********************************************************************/
 
1078
 
 
1079
inline void Graph::maxflow_init()
 
1080
{
 
1081
  node *i;
 
1082
  node_block *nb;
 
1083
 
 
1084
  queue_first[0] = queue_last[0] = NULL;
 
1085
  queue_first[1] = queue_last[1] = NULL;
 
1086
  orphan_first = NULL;
 
1087
 
 
1088
  for (nb=node_block_first; nb; nb=nb->next)
 
1089
    for (i=&nb->nodes[0]; i<nb->current; i++) {
 
1090
      i -> next = NULL;
 
1091
      i -> TS = 0;
 
1092
      if (i->tr_cap > 0) {
 
1093
        /* i is connected to the source */
 
1094
        i -> is_sink = 0;
 
1095
        i -> parent = TERMINAL;
 
1096
        set_active(i);
 
1097
        i -> TS = 0;
 
1098
        i -> DIST = 1;
 
1099
      } else if (i->tr_cap < 0) {
 
1100
        /* i is connected to the sink */
 
1101
        i -> is_sink = 1;
 
1102
        i -> parent = TERMINAL;
 
1103
        set_active(i);
 
1104
        i -> TS = 0;
 
1105
        i -> DIST = 1;
 
1106
      } else {
 
1107
        i -> parent = NULL;
 
1108
      }
 
1109
    }
 
1110
  TIME = 0;
 
1111
}
 
1112
 
 
1113
/***********************************************************************/
 
1114
 
 
1115
inline void Graph::augment(node *s_start, node *t_start, captype *cap_middle,
 
1116
                           captype *rev_cap_middle)
 
1117
{
 
1118
  node *i;
 
1119
  arc_forward *a;
 
1120
  captype bottleneck;
 
1121
  nodeptr *np;
 
1122
 
 
1123
 
 
1124
  /* 1. Finding bottleneck capacity */
 
1125
  /* 1a - the source tree */
 
1126
  bottleneck = *cap_middle;
 
1127
  for (i=s_start; ; ) {
 
1128
    a = i -> parent;
 
1129
    if (a == TERMINAL) break;
 
1130
    if (IS_ODD(a)) {
 
1131
      a = MAKE_EVEN(a);
 
1132
      if (bottleneck > a->r_cap) bottleneck = a -> r_cap;
 
1133
      i = NEIGHBOR_NODE_REV(i, a -> shift);
 
1134
    } else {
 
1135
      if (bottleneck > a->r_rev_cap) bottleneck = a -> r_rev_cap;
 
1136
      i = NEIGHBOR_NODE(i, a -> shift);
 
1137
    }
 
1138
  }
 
1139
  if (bottleneck > i->tr_cap) bottleneck = i -> tr_cap;
 
1140
  /* 1b - the sink tree */
 
1141
  for (i=t_start; ; ) {
 
1142
    a = i -> parent;
 
1143
    if (a == TERMINAL) break;
 
1144
    if (IS_ODD(a)) {
 
1145
      a = MAKE_EVEN(a);
 
1146
      if (bottleneck > a->r_rev_cap) bottleneck = a -> r_rev_cap;
 
1147
      i = NEIGHBOR_NODE_REV(i, a -> shift);
 
1148
    } else {
 
1149
      if (bottleneck > a->r_cap) bottleneck = a -> r_cap;
 
1150
      i = NEIGHBOR_NODE(i, a -> shift);
 
1151
    }
 
1152
  }
 
1153
  if (bottleneck > - i->tr_cap) bottleneck = - i -> tr_cap;
 
1154
 
 
1155
 
 
1156
  /* 2. Augmenting */
 
1157
  /* 2a - the source tree */
 
1158
  *rev_cap_middle += bottleneck;
 
1159
  *cap_middle -= bottleneck;
 
1160
  for (i=s_start; ; ) {
 
1161
    a = i -> parent;
 
1162
    if (a == TERMINAL) break;
 
1163
    if (IS_ODD(a)) {
 
1164
      a = MAKE_EVEN(a);
 
1165
      a -> r_rev_cap += bottleneck;
 
1166
      a -> r_cap -= bottleneck;
 
1167
      if (!a->r_cap) {
 
1168
        /* add i to the adoption list */
 
1169
        i -> parent = ORPHAN;
 
1170
        np = nodeptr_block -> New();
 
1171
        np -> ptr = i;
 
1172
        np -> next = orphan_first;
 
1173
        orphan_first = np;
 
1174
      }
 
1175
      i = NEIGHBOR_NODE_REV(i, a -> shift);
 
1176
    } else {
 
1177
      a -> r_cap += bottleneck;
 
1178
      a -> r_rev_cap -= bottleneck;
 
1179
      if (!a->r_rev_cap) {
 
1180
        /* add i to the adoption list */
 
1181
        i -> parent = ORPHAN;
 
1182
        np = nodeptr_block -> New();
 
1183
        np -> ptr = i;
 
1184
        np -> next = orphan_first;
 
1185
        orphan_first = np;
 
1186
      }
 
1187
      i = NEIGHBOR_NODE(i, a -> shift);
 
1188
    }
 
1189
  }
 
1190
  i -> tr_cap -= bottleneck;
 
1191
  if (!i->tr_cap) {
 
1192
    /* add i to the adoption list */
 
1193
    i -> parent = ORPHAN;
 
1194
    np = nodeptr_block -> New();
 
1195
    np -> ptr = i;
 
1196
    np -> next = orphan_first;
 
1197
    orphan_first = np;
 
1198
  }
 
1199
  /* 2b - the sink tree */
 
1200
  for (i=t_start; ; ) {
 
1201
    a = i -> parent;
 
1202
    if (a == TERMINAL) break;
 
1203
    if (IS_ODD(a)) {
 
1204
      a = MAKE_EVEN(a);
 
1205
      a -> r_cap += bottleneck;
 
1206
      a -> r_rev_cap -= bottleneck;
 
1207
      if (!a->r_rev_cap) {
 
1208
        /* add i to the adoption list */
 
1209
        i -> parent = ORPHAN;
 
1210
        np = nodeptr_block -> New();
 
1211
        np -> ptr = i;
 
1212
        np -> next = orphan_first;
 
1213
        orphan_first = np;
 
1214
      }
 
1215
      i = NEIGHBOR_NODE_REV(i, a -> shift);
 
1216
    } else {
 
1217
      a -> r_rev_cap += bottleneck;
 
1218
      a -> r_cap -= bottleneck;
 
1219
      if (!a->r_cap) {
 
1220
        /* add i to the adoption list */
 
1221
        i -> parent = ORPHAN;
 
1222
        np = nodeptr_block -> New();
 
1223
        np -> ptr = i;
 
1224
        np -> next = orphan_first;
 
1225
        orphan_first = np;
 
1226
      }
 
1227
      i = NEIGHBOR_NODE(i, a -> shift);
 
1228
    }
 
1229
  }
 
1230
  i -> tr_cap += bottleneck;
 
1231
  if (!i->tr_cap) {
 
1232
    /* add i to the adoption list */
 
1233
    i -> parent = ORPHAN;
 
1234
    np = nodeptr_block -> New();
 
1235
    np -> ptr = i;
 
1236
    np -> next = orphan_first;
 
1237
    orphan_first = np;
 
1238
  }
 
1239
 
 
1240
 
 
1241
  flow += bottleneck;
 
1242
}
 
1243
 
 
1244
/***********************************************************************/
 
1245
 
 
1246
inline void Graph::process_source_orphan(node *i)
 
1247
{
 
1248
  node *j;
 
1249
  arc_forward *a0_for, *a0_for_first, *a0_for_last;
 
1250
  arc_reverse *a0_rev, *a0_rev_first, *a0_rev_last;
 
1251
  arc_forward *a0_min = NULL, *a;
 
1252
  nodeptr *np;
 
1253
  int d, d_min = INFINITE_D;
 
1254
 
 
1255
  /* trying to find a new parent */
 
1256
  a0_for_first = i -> first_out;
 
1257
  if (IS_ODD(a0_for_first)) {
 
1258
    a0_for_first = (arc_forward *) (((char *)a0_for_first) + 1);
 
1259
    a0_for_last = (arc_forward *) ((a0_for_first ++) -> shift);
 
1260
  } else a0_for_last = (i + 1) -> first_out;
 
1261
  a0_rev_first = i -> first_in;
 
1262
  if (IS_ODD(a0_rev_first)) {
 
1263
    a0_rev_first = (arc_reverse *) (((char *)a0_rev_first) + 1);
 
1264
    a0_rev_last  = (arc_reverse *) ((a0_rev_first ++) -> sister);
 
1265
  } else a0_rev_last = (i + 1) -> first_in;
 
1266
 
 
1267
 
 
1268
  for (a0_for=a0_for_first; a0_for<a0_for_last; a0_for++)
 
1269
    if (a0_for->r_rev_cap) {
 
1270
      j = NEIGHBOR_NODE(i, a0_for -> shift);
 
1271
      if (!j->is_sink && (a=j->parent)) {
 
1272
        /* checking the origin of j */
 
1273
        d = 0;
 
1274
        while ( 1 ) {
 
1275
          if (j->TS == TIME) {
 
1276
            d += j -> DIST;
 
1277
            break;
 
1278
          }
 
1279
          a = j -> parent;
 
1280
          d ++;
 
1281
          if (a==TERMINAL) {
 
1282
            j -> TS = TIME;
 
1283
            j -> DIST = 1;
 
1284
            break;
 
1285
          }
 
1286
          if (a==ORPHAN) {
 
1287
            d = INFINITE_D;
 
1288
            break;
 
1289
          }
 
1290
          if (IS_ODD(a))
 
1291
            j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1292
          else
 
1293
            j = NEIGHBOR_NODE(j, a -> shift);
 
1294
        }
 
1295
        if (d<INFINITE_D) { /* j originates from the source - done */
 
1296
          if (d<d_min) {
 
1297
            a0_min = a0_for;
 
1298
            d_min = d;
 
1299
          }
 
1300
          /* set marks along the path */
 
1301
          for (j=NEIGHBOR_NODE(i, a0_for->shift); j->TS!=TIME; ) {
 
1302
            j -> TS = TIME;
 
1303
            j -> DIST = d --;
 
1304
            a = j->parent;
 
1305
            if (IS_ODD(a))
 
1306
              j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1307
            else
 
1308
              j = NEIGHBOR_NODE(j, a -> shift);
 
1309
          }
 
1310
        }
 
1311
      }
 
1312
    }
 
1313
  for (a0_rev=a0_rev_first; a0_rev<a0_rev_last; a0_rev++) {
 
1314
    a0_for = a0_rev -> sister;
 
1315
    if (a0_for->r_cap) {
 
1316
      j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
 
1317
      if (!j->is_sink && (a=j->parent)) {
 
1318
        /* checking the origin of j */
 
1319
        d = 0;
 
1320
        while ( 1 ) {
 
1321
          if (j->TS == TIME) {
 
1322
            d += j -> DIST;
 
1323
            break;
 
1324
          }
 
1325
          a = j -> parent;
 
1326
          d ++;
 
1327
          if (a==TERMINAL) {
 
1328
            j -> TS = TIME;
 
1329
            j -> DIST = 1;
 
1330
            break;
 
1331
          }
 
1332
          if (a==ORPHAN) {
 
1333
            d = INFINITE_D;
 
1334
            break;
 
1335
          }
 
1336
          if (IS_ODD(a))
 
1337
            j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1338
          else
 
1339
            j = NEIGHBOR_NODE(j, a -> shift);
 
1340
        }
 
1341
        if (d<INFINITE_D) { /* j originates from the source - done */
 
1342
          if (d<d_min) {
 
1343
            a0_min = MAKE_ODD(a0_for);
 
1344
            d_min = d;
 
1345
          }
 
1346
          /* set marks along the path */
 
1347
          for (j=NEIGHBOR_NODE_REV(i,a0_for->shift); j->TS!=TIME; ) {
 
1348
            j -> TS = TIME;
 
1349
            j -> DIST = d --;
 
1350
            a = j->parent;
 
1351
            if (IS_ODD(a))
 
1352
              j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1353
            else
 
1354
              j = NEIGHBOR_NODE(j, a -> shift);
 
1355
          }
 
1356
        }
 
1357
      }
 
1358
    }
 
1359
  }
 
1360
 
 
1361
  if ( (i->parent = a0_min) ) {
 
1362
    i -> TS = TIME;
 
1363
    i -> DIST = d_min + 1;
 
1364
  } else {
 
1365
    /* no parent is found */
 
1366
    i -> TS = 0;
 
1367
 
 
1368
    /* process neighbors */
 
1369
    for (a0_for=a0_for_first; a0_for<a0_for_last; a0_for++) {
 
1370
      j = NEIGHBOR_NODE(i, a0_for -> shift);
 
1371
      if (!j->is_sink && (a=j->parent)) {
 
1372
        if (a0_for->r_rev_cap) set_active(j);
 
1373
        if (a!=TERMINAL && a!=ORPHAN && IS_ODD(a)
 
1374
            && NEIGHBOR_NODE_REV(j, MAKE_EVEN(a)->shift)==i) {
 
1375
          /* add j to the adoption list */
 
1376
          j -> parent = ORPHAN;
 
1377
          np = nodeptr_block -> New();
 
1378
          np -> ptr = j;
 
1379
          if (orphan_last) orphan_last -> next = np;
 
1380
          else             orphan_first        = np;
 
1381
          orphan_last = np;
 
1382
          np -> next = NULL;
 
1383
        }
 
1384
      }
 
1385
    }
 
1386
    for (a0_rev=a0_rev_first; a0_rev<a0_rev_last; a0_rev++) {
 
1387
      a0_for = a0_rev -> sister;
 
1388
      j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
 
1389
      if (!j->is_sink && (a=j->parent)) {
 
1390
        if (a0_for->r_cap) set_active(j);
 
1391
        if (a!=TERMINAL && a!=ORPHAN && !IS_ODD(a) && NEIGHBOR_NODE(j, a->shift)==i) {
 
1392
          /* add j to the adoption list */
 
1393
          j -> parent = ORPHAN;
 
1394
          np = nodeptr_block -> New();
 
1395
          np -> ptr = j;
 
1396
          if (orphan_last) orphan_last -> next = np;
 
1397
          else             orphan_first        = np;
 
1398
          orphan_last = np;
 
1399
          np -> next = NULL;
 
1400
        }
 
1401
      }
 
1402
    }
 
1403
  }
 
1404
}
 
1405
 
 
1406
inline void Graph::process_sink_orphan(node *i)
 
1407
{
 
1408
  node *j;
 
1409
  arc_forward *a0_for, *a0_for_first, *a0_for_last;
 
1410
  arc_reverse *a0_rev, *a0_rev_first, *a0_rev_last;
 
1411
  arc_forward *a0_min = NULL, *a;
 
1412
  nodeptr *np;
 
1413
  int d, d_min = INFINITE_D;
 
1414
 
 
1415
  /* trying to find a new parent */
 
1416
  a0_for_first = i -> first_out;
 
1417
  if (IS_ODD(a0_for_first)) {
 
1418
    a0_for_first = (arc_forward *) (((char *)a0_for_first) + 1);
 
1419
    a0_for_last = (arc_forward *) ((a0_for_first ++) -> shift);
 
1420
  } else a0_for_last = (i + 1) -> first_out;
 
1421
  a0_rev_first = i -> first_in;
 
1422
  if (IS_ODD(a0_rev_first)) {
 
1423
    a0_rev_first = (arc_reverse *) (((char *)a0_rev_first) + 1);
 
1424
    a0_rev_last  = (arc_reverse *) ((a0_rev_first ++) -> sister);
 
1425
  } else a0_rev_last = (i + 1) -> first_in;
 
1426
 
 
1427
 
 
1428
  for (a0_for=a0_for_first; a0_for<a0_for_last; a0_for++)
 
1429
    if (a0_for->r_cap) {
 
1430
      j = NEIGHBOR_NODE(i, a0_for -> shift);
 
1431
      if (j->is_sink && (a=j->parent)) {
 
1432
        /* checking the origin of j */
 
1433
        d = 0;
 
1434
        while ( 1 ) {
 
1435
          if (j->TS == TIME) {
 
1436
            d += j -> DIST;
 
1437
            break;
 
1438
          }
 
1439
          a = j -> parent;
 
1440
          d ++;
 
1441
          if (a==TERMINAL) {
 
1442
            j -> TS = TIME;
 
1443
            j -> DIST = 1;
 
1444
            break;
 
1445
          }
 
1446
          if (a==ORPHAN) {
 
1447
            d = INFINITE_D;
 
1448
            break;
 
1449
          }
 
1450
          if (IS_ODD(a))
 
1451
            j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1452
          else
 
1453
            j = NEIGHBOR_NODE(j, a -> shift);
 
1454
        }
 
1455
        if (d<INFINITE_D) { /* j originates from the sink - done */
 
1456
          if (d<d_min) {
 
1457
            a0_min = a0_for;
 
1458
            d_min = d;
 
1459
          }
 
1460
          /* set marks along the path */
 
1461
          for (j=NEIGHBOR_NODE(i, a0_for->shift); j->TS!=TIME; ) {
 
1462
            j -> TS = TIME;
 
1463
            j -> DIST = d --;
 
1464
            a = j->parent;
 
1465
            if (IS_ODD(a))
 
1466
              j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1467
            else
 
1468
              j = NEIGHBOR_NODE(j, a -> shift);
 
1469
          }
 
1470
        }
 
1471
      }
 
1472
    }
 
1473
  for (a0_rev=a0_rev_first; a0_rev<a0_rev_last; a0_rev++) {
 
1474
    a0_for = a0_rev -> sister;
 
1475
    if (a0_for->r_rev_cap) {
 
1476
      j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
 
1477
      if (j->is_sink && (a=j->parent)) {
 
1478
        /* checking the origin of j */
 
1479
        d = 0;
 
1480
        while ( 1 ) {
 
1481
          if (j->TS == TIME) {
 
1482
            d += j -> DIST;
 
1483
            break;
 
1484
          }
 
1485
          a = j -> parent;
 
1486
          d ++;
 
1487
          if (a==TERMINAL) {
 
1488
            j -> TS = TIME;
 
1489
            j -> DIST = 1;
 
1490
            break;
 
1491
          }
 
1492
          if (a==ORPHAN) {
 
1493
            d = INFINITE_D;
 
1494
            break;
 
1495
          }
 
1496
          if (IS_ODD(a))
 
1497
            j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1498
          else
 
1499
            j = NEIGHBOR_NODE(j, a -> shift);
 
1500
        }
 
1501
        if (d<INFINITE_D) { /* j originates from the sink - done */
 
1502
          if (d<d_min) {
 
1503
            a0_min = MAKE_ODD(a0_for);
 
1504
            d_min = d;
 
1505
          }
 
1506
          /* set marks along the path */
 
1507
          for (j=NEIGHBOR_NODE_REV(i,a0_for->shift); j->TS!=TIME; ) {
 
1508
            j -> TS = TIME;
 
1509
            j -> DIST = d --;
 
1510
            a = j->parent;
 
1511
            if (IS_ODD(a))
 
1512
              j = NEIGHBOR_NODE_REV(j, MAKE_EVEN(a) -> shift);
 
1513
            else
 
1514
              j = NEIGHBOR_NODE(j, a -> shift);
 
1515
          }
 
1516
        }
 
1517
      }
 
1518
    }
 
1519
  }
 
1520
 
 
1521
  if ( (i->parent = a0_min) ) {
 
1522
    i -> TS = TIME;
 
1523
    i -> DIST = d_min + 1;
 
1524
  } else {
 
1525
    /* no parent is found */
 
1526
    i -> TS = 0;
 
1527
 
 
1528
    /* process neighbors */
 
1529
    for (a0_for=a0_for_first; a0_for<a0_for_last; a0_for++) {
 
1530
      j = NEIGHBOR_NODE(i, a0_for -> shift);
 
1531
      if (j->is_sink && (a=j->parent)) {
 
1532
        if (a0_for->r_cap) set_active(j);
 
1533
        if (a!=TERMINAL && a!=ORPHAN && IS_ODD(a)
 
1534
            && NEIGHBOR_NODE_REV(j, MAKE_EVEN(a)->shift)==i) {
 
1535
          /* add j to the adoption list */
 
1536
          j -> parent = ORPHAN;
 
1537
          np = nodeptr_block -> New();
 
1538
          np -> ptr = j;
 
1539
          if (orphan_last) orphan_last -> next = np;
 
1540
          else             orphan_first        = np;
 
1541
          orphan_last = np;
 
1542
          np -> next = NULL;
 
1543
        }
 
1544
      }
 
1545
    }
 
1546
    for (a0_rev=a0_rev_first; a0_rev<a0_rev_last; a0_rev++) {
 
1547
      a0_for = a0_rev -> sister;
 
1548
      j = NEIGHBOR_NODE_REV(i, a0_for -> shift);
 
1549
      if (j->is_sink && (a=j->parent)) {
 
1550
        if (a0_for->r_rev_cap) set_active(j);
 
1551
        if (a!=TERMINAL && a!=ORPHAN && !IS_ODD(a) && NEIGHBOR_NODE(j, a->shift)==i) {
 
1552
          /* add j to the adoption list */
 
1553
          j -> parent = ORPHAN;
 
1554
          np = nodeptr_block -> New();
 
1555
          np -> ptr = j;
 
1556
          if (orphan_last) orphan_last -> next = np;
 
1557
          else             orphan_first        = np;
 
1558
          orphan_last = np;
 
1559
          np -> next = NULL;
 
1560
        }
 
1561
      }
 
1562
    }
 
1563
  }
 
1564
}
 
1565
 
 
1566
/***********************************************************************/
 
1567
 
 
1568
inline Graph::flowtype Graph::maxflow()
 
1569
{
 
1570
  node *i, *j, *current_node = NULL, *s_start, *t_start=NULL;
 
1571
  captype *cap_middle=NULL, *rev_cap_middle=NULL;
 
1572
  arc_forward *a_for, *a_for_first, *a_for_last;
 
1573
  arc_reverse *a_rev, *a_rev_first, *a_rev_last;
 
1574
  nodeptr *np, *np_next;
 
1575
 
 
1576
  prepare_graph();
 
1577
  maxflow_init();
 
1578
  nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function);
 
1579
 
 
1580
  while ( 1 ) {
 
1581
    if ( (i=current_node) ) {
 
1582
      i -> next = NULL; /* remove active flag */
 
1583
      if (!i->parent) i = NULL;
 
1584
    }
 
1585
    if (!i) {
 
1586
      if (!(i = next_active())) break;
 
1587
    }
 
1588
 
 
1589
    /* growth */
 
1590
    s_start = NULL;
 
1591
 
 
1592
    a_for_first = i -> first_out;
 
1593
    if (IS_ODD(a_for_first)) {
 
1594
      a_for_first = (arc_forward *) (((char *)a_for_first) + 1);
 
1595
      a_for_last = (arc_forward *) ((a_for_first ++) -> shift);
 
1596
    } else a_for_last = (i + 1) -> first_out;
 
1597
    a_rev_first = i -> first_in;
 
1598
    if (IS_ODD(a_rev_first)) {
 
1599
      a_rev_first = (arc_reverse *) (((char *)a_rev_first) + 1);
 
1600
      a_rev_last = (arc_reverse *) ((a_rev_first ++) -> sister);
 
1601
    } else a_rev_last = (i + 1) -> first_in;
 
1602
 
 
1603
    if (!i->is_sink) {
 
1604
      /* grow source tree */
 
1605
      for (a_for=a_for_first; a_for<a_for_last; a_for++)
 
1606
        if (a_for->r_cap) {
 
1607
          j = NEIGHBOR_NODE(i, a_for -> shift);
 
1608
          if (!j->parent) {
 
1609
            j -> is_sink = 0;
 
1610
            j -> parent = MAKE_ODD(a_for);
 
1611
            j -> TS = i -> TS;
 
1612
            j -> DIST = i -> DIST + 1;
 
1613
            set_active(j);
 
1614
          } else if (j->is_sink) {
 
1615
            s_start = i;
 
1616
            t_start = j;
 
1617
            cap_middle     = & ( a_for -> r_cap );
 
1618
            rev_cap_middle = & ( a_for -> r_rev_cap );
 
1619
            break;
 
1620
          } else if (j->TS <= i->TS &&
 
1621
                     j->DIST > i->DIST) {
 
1622
            /* heuristic - trying to make the distance from j to the source shorter */
 
1623
            j -> parent = MAKE_ODD(a_for);
 
1624
            j -> TS = i -> TS;
 
1625
            j -> DIST = i -> DIST + 1;
 
1626
          }
 
1627
        }
 
1628
      if (!s_start)
 
1629
        for (a_rev=a_rev_first; a_rev<a_rev_last; a_rev++) {
 
1630
          a_for = a_rev -> sister;
 
1631
          if (a_for->r_rev_cap) {
 
1632
            j = NEIGHBOR_NODE_REV(i, a_for -> shift);
 
1633
            if (!j->parent) {
 
1634
              j -> is_sink = 0;
 
1635
              j -> parent = a_for;
 
1636
              j -> TS = i -> TS;
 
1637
              j -> DIST = i -> DIST + 1;
 
1638
              set_active(j);
 
1639
            } else if (j->is_sink) {
 
1640
              s_start = i;
 
1641
              t_start = j;
 
1642
              cap_middle     = & ( a_for -> r_rev_cap );
 
1643
              rev_cap_middle = & ( a_for -> r_cap );
 
1644
              break;
 
1645
            } else if (j->TS <= i->TS &&
 
1646
                       j->DIST > i->DIST) {
 
1647
              /* heuristic - trying to make the distance from j to the source shorter */
 
1648
              j -> parent = a_for;
 
1649
              j -> TS = i -> TS;
 
1650
              j -> DIST = i -> DIST + 1;
 
1651
            }
 
1652
          }
 
1653
        }
 
1654
    } else {
 
1655
      /* grow sink tree */
 
1656
      for (a_for=a_for_first; a_for<a_for_last; a_for++)
 
1657
        if (a_for->r_rev_cap) {
 
1658
          j = NEIGHBOR_NODE(i, a_for -> shift);
 
1659
          if (!j->parent) {
 
1660
            j -> is_sink = 1;
 
1661
            j -> parent = MAKE_ODD(a_for);
 
1662
            j -> TS = i -> TS;
 
1663
            j -> DIST = i -> DIST + 1;
 
1664
            set_active(j);
 
1665
          } else if (!j->is_sink) {
 
1666
            s_start = j;
 
1667
            t_start = i;
 
1668
            cap_middle     = & ( a_for -> r_rev_cap );
 
1669
            rev_cap_middle = & ( a_for -> r_cap );
 
1670
            break;
 
1671
          } else if (j->TS <= i->TS &&
 
1672
                     j->DIST > i->DIST) {
 
1673
            /* heuristic - trying to make the distance from j to the sink shorter */
 
1674
            j -> parent = MAKE_ODD(a_for);
 
1675
            j -> TS = i -> TS;
 
1676
            j -> DIST = i -> DIST + 1;
 
1677
          }
 
1678
        }
 
1679
      for (a_rev=a_rev_first; a_rev<a_rev_last; a_rev++) {
 
1680
        a_for = a_rev -> sister;
 
1681
        if (a_for->r_cap) {
 
1682
          j = NEIGHBOR_NODE_REV(i, a_for -> shift);
 
1683
          if (!j->parent) {
 
1684
            j -> is_sink = 1;
 
1685
            j -> parent = a_for;
 
1686
            j -> TS = i -> TS;
 
1687
            j -> DIST = i -> DIST + 1;
 
1688
            set_active(j);
 
1689
          } else if (!j->is_sink) {
 
1690
            s_start = j;
 
1691
            t_start = i;
 
1692
            cap_middle     = & ( a_for -> r_cap );
 
1693
            rev_cap_middle = & ( a_for -> r_rev_cap );
 
1694
            break;
 
1695
          } else if (j->TS <= i->TS &&
 
1696
                     j->DIST > i->DIST) {
 
1697
            /* heuristic - trying to make the distance from j to the sink shorter */
 
1698
            j -> parent = a_for;
 
1699
            j -> TS = i -> TS;
 
1700
            j -> DIST = i -> DIST + 1;
 
1701
          }
 
1702
        }
 
1703
      }
 
1704
    }
 
1705
 
 
1706
    TIME ++;
 
1707
 
 
1708
    if (s_start) {
 
1709
      i -> next = i; /* set active flag */
 
1710
      current_node = i;
 
1711
 
 
1712
      /* augmentation */
 
1713
      augment(s_start, t_start, cap_middle, rev_cap_middle);
 
1714
      /* augmentation end */
 
1715
 
 
1716
      /* adoption */
 
1717
      while ( (np=orphan_first) ) {
 
1718
        np_next = np -> next;
 
1719
        np -> next = NULL;
 
1720
 
 
1721
        while ( (np=orphan_first) ) {
 
1722
          orphan_first = np -> next;
 
1723
          i = np -> ptr;
 
1724
          nodeptr_block -> Delete(np);
 
1725
          if (!orphan_first) orphan_last = NULL;
 
1726
          if (i->is_sink) process_sink_orphan(i);
 
1727
          else            process_source_orphan(i);
 
1728
        }
 
1729
 
 
1730
        orphan_first = np_next;
 
1731
      }
 
1732
      /* adoption end */
 
1733
    } else current_node = NULL;
 
1734
  }
 
1735
 
 
1736
  delete nodeptr_block;
 
1737
 
 
1738
  return flow;
 
1739
}
 
1740
 
 
1741
/***********************************************************************/
 
1742
 
 
1743
inline Graph::termtype Graph::what_segment(node_id i)
 
1744
{
 
1745
  if (((node*)i)->parent && !((node*)i)->is_sink) return SOURCE;
 
1746
  return SINK;
 
1747
}
 
1748
 
 
1749
#endif