00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include "graph.h"
00004
00005
00006 static node **active;
00007 static long *number;
00008 static long max_dist, bound;
00009 static BOOL co_check;
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 BOOL init_maxflow (long n)
00022 {
00023 active = (node **) malloc ((n+1L) * sizeof (node *));
00024
00025 if (active == (node **) 0)
00026 { printf ("Unable to allocate memory\n");
00027 return (FALSE);
00028 }
00029 number = (long *) malloc ((n+1L) * sizeof (long));
00030
00031
00032
00033 if (number == (long *) 0)
00034 { printf ("Unable to allocate memory\n");
00035 return (FALSE);
00036 }
00037 co_check = TRUE;
00038 return (TRUE);
00039
00040 }
00041
00042
00043 void fini_maxflow ()
00044 {
00045 free (active);
00046 free (number);
00047
00048 }
00049
00050
00051 void global_relabel (graph *gr, node *tptr)
00052 {
00053
00054
00055
00056 node *front, *rear, *nptr, **ptr;
00057 edge *eptr;
00058 long n, level, count, i;
00059
00060 n = gr->n_nodes;
00061 for (nptr = &(gr->nodes[n-1L]); nptr >= gr->nodes; nptr--)
00062 { nptr->unmarked = TRUE;
00063 nptr->stack_link = NILN;
00064 nptr->scan_ptr = nptr->first_edge;
00065 }
00066 tptr->unmarked = FALSE;
00067
00068 for (ptr = &(active[n]); ptr >= active; ptr--)
00069 *ptr = NILN;
00070 for (i = 0L; i <= n; i++)
00071 number[i] = 0L;
00072 max_dist = 0L;
00073 count = 1L;
00074 front = tptr;
00075 rear = front;
00076
00077 bfs_next:
00078 level = rear->dist + 1L;
00079 eptr = rear->first_edge;
00080 while (eptr != NILE)
00081 { nptr = eptr->adjac;
00082 if (nptr->alive && nptr->unmarked
00083 && eptr->back->rcap > EPS)
00084 { nptr->unmarked = FALSE;
00085 nptr->dist = level;
00086 ++count;
00087 ++number[level];
00088 if (nptr->excess > EPS)
00089 { nptr->stack_link = active[level];
00090 active[level] = nptr;
00091 max_dist = level;
00092 }
00093 front->bfs_link = nptr;
00094 front = nptr;
00095 }
00096 eptr = eptr->next;
00097 }
00098 if (front == rear)
00099 goto bfs_ready;
00100
00101 rear = rear->bfs_link;
00102 goto bfs_next;
00103
00104 bfs_ready:
00105
00106 if (count < bound)
00107 {
00108
00109 for (nptr = &(gr->nodes[n-1L]); nptr >= gr->nodes; nptr--)
00110 if (nptr->unmarked && nptr->alive)
00111 { nptr->dist = n;
00112 nptr->alive = FALSE;
00113 }
00114 bound = count;
00115 }
00116
00117 }
00118
00119
00120 double maxflow (graph *gr, node *s_ptr, node *t_ptr)
00121 {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 node *aptr, *nptr, *q_front, *q_rear;
00132 node **ptr;
00133 edge *eptr;
00134 long n, m, m0, level, i, n_discharge;
00135 double incre;
00136 long count, dist, dmin, *upper, *lower;
00137 double cap;
00138 char any;
00139
00140
00141
00142
00143 n = gr->n_nodes;
00144 for (nptr = &(gr->nodes[n-1L]); nptr >= gr->nodes; nptr--)
00145 { nptr->scan_ptr = nptr->first_edge;
00146
00147
00148
00149
00150 if (nptr->scan_ptr == NILE)
00151 { fprintf (stderr, "isolated node in input graph\n");
00152 return (FALSE);
00153 }
00154 nptr->excess = 0.0L;
00155 nptr->stack_link = NILN;
00156 nptr->alive = TRUE;
00157 nptr->unmarked = TRUE;
00158 }
00159 m = gr->n_edges;
00160 m0 = gr->n_edges0;
00161 for (eptr = &(gr->edges[m-1L]); eptr >= gr->edges; eptr--)
00162 eptr->rcap = eptr->cap;
00163 for (eptr = &(gr->edges[m0+m-1L]); eptr >= &(gr->edges[m0]); eptr--)
00164 eptr->rcap = eptr->cap;
00165
00166 for (i = n; i >= 0L; i--)
00167 { number[i] = 0L;
00168 active[i] = NILN;
00169 }
00170 t_ptr->dist = 0L;
00171
00172
00173
00174
00175 t_ptr->unmarked = FALSE;
00176 q_front = t_ptr;
00177 q_rear = q_front;
00178 bfs_next:
00179 level = q_rear->dist + 1L;
00180 eptr = q_rear->first_edge;
00181 while (eptr != NILE)
00182 { if (eptr->adjac->unmarked && eptr->back->rcap > EPS)
00183 { nptr = eptr->adjac;
00184 nptr->unmarked = FALSE;
00185 nptr->dist = level;
00186 ++number[level];
00187 q_front->bfs_link = nptr;
00188 q_front = nptr;
00189 }
00190 eptr = eptr->next;
00191 }
00192 if (q_rear == q_front)
00193 goto bfs_ready;
00194
00195 q_rear = q_rear->bfs_link;
00196 goto bfs_next;
00197
00198 bfs_ready:
00199 if (co_check)
00200 { co_check = FALSE;
00201 for (nptr = &(gr->nodes[n-1]); nptr >= gr->nodes; --nptr)
00202 if (nptr->unmarked)
00203 { fprintf (stderr,"Input graph not connected\n");
00204 return (-1.0L);
00205 }
00206 }
00207
00208
00209 s_ptr->dist = n;
00210 t_ptr->dist = 0L;
00211 t_ptr->excess = 1.0L;
00212
00213
00214
00215
00216 max_dist = 0L;
00217 eptr = s_ptr->first_edge;
00218 while (eptr != NILE)
00219 { nptr = eptr->adjac;
00220 cap = eptr->rcap;
00221 nptr->excess += cap;
00222 s_ptr->excess -= cap;
00223 eptr->back->rcap += cap;
00224 eptr->rcap = 0.0L;
00225
00226 if (nptr != t_ptr && nptr->excess <= cap + EPS)
00227 {
00228
00229 nptr->stack_link = active[nptr->dist];
00230 active[nptr->dist] = nptr;
00231 if (nptr->dist > max_dist)
00232 max_dist = nptr->dist;
00233 }
00234 eptr = eptr->next;
00235 }
00236
00237 s_ptr->alive = FALSE;
00238 bound = n;
00239 n_discharge = 0L;
00240
00241
00242
00243 do {
00244 aptr = active[max_dist];
00245 while (aptr != NILN)
00246 { active[max_dist] = aptr->stack_link;
00247 eptr = aptr->scan_ptr;
00248
00249 edge_scan:
00250 nptr = eptr->adjac;
00251 if (nptr->dist == aptr->dist - 1L &&
00252 eptr->rcap > EPS)
00253 { incre = aptr->excess;
00254 if (incre <= eptr->rcap)
00255 {
00256 eptr->rcap -= incre;
00257 eptr->back->rcap += incre;
00258 aptr->excess = 0.0L;
00259 nptr->excess += incre;
00260 if (nptr->excess <= incre + EPS)
00261 {
00262 nptr->stack_link = active[nptr->dist];
00263 active[nptr->dist] = nptr;
00264 }
00265 aptr->scan_ptr = eptr;
00266 goto node_ready;
00267 }
00268 else
00269 {
00270 incre = eptr->rcap;
00271 eptr->back->rcap += incre;
00272 aptr->excess -= incre;
00273 nptr->excess += incre;
00274 eptr->rcap = 0.0L;
00275 if (nptr->excess <= incre + EPS)
00276 {
00277 nptr->stack_link = active[nptr->dist];
00278 active[nptr->dist] = nptr;
00279 }
00280 if (aptr->excess <= EPS)
00281 { aptr->scan_ptr = eptr;
00282 goto node_ready;
00283 }
00284 }
00285 }
00286 if (eptr->next == NILE)
00287 {
00288
00289
00290
00291 if (number[aptr->dist] == 1L)
00292 {
00293
00294
00295
00296 for (nptr = &(gr->nodes[n-1L]);
00297 nptr >= gr->nodes; nptr--)
00298 if (nptr->alive &&
00299 nptr->dist > aptr->dist)
00300 { --number[nptr->dist];
00301 active[nptr->dist] = NILN;
00302 nptr->alive = FALSE;
00303 nptr->dist = n;
00304 --bound;
00305 }
00306 --number[aptr->dist];
00307 active[aptr->dist] = NILN;
00308 aptr->alive = FALSE;
00309 aptr->dist = n;
00310 --bound;
00311 goto node_ready;
00312 }
00313 else
00314 {
00315 dmin = n;
00316 aptr->scan_ptr = NILE;
00317 eptr = aptr->first_edge;
00318 while (eptr != NILE)
00319 { if (eptr->adjac->dist < dmin
00320 && eptr->rcap > EPS)
00321 { dmin = eptr->adjac->dist;
00322 if (aptr->scan_ptr == NILE)
00323 aptr->scan_ptr = eptr;
00324 }
00325 eptr = eptr->next;
00326 }
00327 if (++dmin < bound)
00328 {
00329 --number[aptr->dist];
00330 aptr->dist = dmin;
00331 ++number[dmin];
00332 max_dist = dmin;
00333 eptr = aptr->scan_ptr;
00334 goto edge_scan;
00335 }
00336 else
00337 { aptr->alive = FALSE;
00338 --number[aptr->dist];
00339 aptr->dist = n;
00340 --bound;
00341 goto node_ready;
00342 }
00343 }
00344 }
00345 else
00346 { eptr = eptr->next;
00347 goto edge_scan;
00348 }
00349
00350 node_ready:
00351 ++n_discharge;
00352 if (n_discharge == n)
00353 { n_discharge = 0L;
00354 global_relabel (gr, t_ptr);
00355 }
00356 aptr = active[max_dist];
00357 }
00358 --max_dist;
00359 }
00360 while (max_dist > 0L);
00361
00362 return (t_ptr->excess - 1.0L);
00363 }
00364
00365 BOOL ghc_tree (graph *gr)
00366 {
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 node *nptr, *nptr1, *nptrn, *sptr, *tptr;
00387 edge *eptr;
00388 long n, m;
00389 double maxfl;
00390
00391
00392 n = gr->n_nodes;
00393 m = gr->n_edges;
00394
00395 if (! init_maxflow (n))
00396 return (FALSE);
00397
00398 nptr1 = gr->nodes;
00399 nptrn = &(gr->nodes[n-1L]);
00400 for (nptr = nptrn; nptr >= nptr1; nptr--)
00401 nptr->parent = nptr1;
00402
00403 for (sptr = &(gr->nodes[1L]); sptr <= nptrn; sptr++)
00404 { tptr = sptr->parent;
00405 maxfl = maxflow (gr, sptr, tptr);
00406 if (maxfl < 0L)
00407 return (FALSE);
00408
00409 sptr->mincap = maxfl;
00410 for (nptr = &(gr->nodes[1L]); nptr <= nptrn; nptr++)
00411 if (nptr != sptr &&
00412 ! nptr->alive && nptr->parent == tptr)
00413 nptr->parent = sptr;
00414 if (! tptr->parent->alive)
00415 { sptr->parent = tptr->parent;
00416 tptr->parent = sptr;
00417 sptr->mincap = tptr->mincap;
00418 tptr->mincap = maxfl;
00419 }
00420 }
00421 fini_maxflow ();
00422
00423 }