00001
00002
00003
00004
00005
00006
00007 #define GRAPHISOLATOR_C
00008
00009 #include "graph_boyer.h"
00010
00011
00012 extern void _FillVisitedFlags (graphP,
00013 int);
00014 extern int _GetNextVertexOnExternalFace (graphP theGraph,
00015 int curVertex,
00016 int *pPrevLink);
00017 extern int _JoinBicomps (graphP theGraph);
00018 extern void _RecordPertinentChildBicomp (graphP theGraph,
00019 int I,
00020 int RootVertex);
00021 extern int _GetPertinentChildBicomp (graphP theGraph,
00022 int W);
00023 extern int _ChooseTypeOfNonplanarityMinor (graphP theGraph,
00024 int I,
00025 int R);
00026
00027
00028 int _IsolateKuratowskiSubgraph (graphP theGraph,
00029 int I);
00030 int _FindUnembeddedEdgeToAncestor (graphP theGraph,
00031 int cutVertex,
00032 int *pAncestor,
00033 int *pDescendant);
00034 int _FindUnembeddedEdgeToCurVertex (graphP theGraph,
00035 int cutVertex,
00036 int *pDescendant);
00037 int _FindUnembeddedEdgeToSubtree (graphP theGraph,
00038 int ancestor,
00039 int SubtreeRoot,
00040 int *pDescendant);
00041 int _MarkDFSPath (graphP theGraph,
00042 int ancestor,
00043 int descendant);
00044 int _MarkPathAlongBicompExtFace (graphP theGraph,
00045 int startVert,
00046 int endVert);
00047 int _AddAndMarkEdge (graphP theGraph,
00048 int ancestor,
00049 int descendant);
00050 void _AddBackEdge (graphP theGraph,
00051 int ancestor,
00052 int descendant);
00053 int _DeleteUnmarkedVerticesAndEdges (graphP theGraph);
00054 int _InitializeIsolatorContext (graphP theGraph);
00055 int _IsolateMinorA (graphP theGraph);
00056 int _IsolateMinorB (graphP theGraph);
00057 int _IsolateMinorC (graphP theGraph);
00058 int _IsolateMinorD (graphP theGraph);
00059 int _IsolateMinorE (graphP theGraph);
00060 int _IsolateMinorE1 (graphP theGraph);
00061 int _IsolateMinorE2 (graphP theGraph);
00062 int _IsolateMinorE3 (graphP theGraph);
00063 int _IsolateMinorE4 (graphP theGraph);
00064 int _GetLeastAncestorConnection (graphP theGraph,
00065 int cutVertex);
00066 int _MarkDFSPathsToDescendants (graphP theGraph);
00067 int _AddAndMarkUnembeddedEdges (graphP theGraph);
00068
00069
00070
00071
00072 int _IsolateKuratowskiSubgraph (graphP theGraph,
00073 int I)
00074 {
00075
00076
00077
00078
00079 int RetVal = NOTOK;
00080
00081
00082
00083 if (_ChooseTypeOfNonplanarityMinor (theGraph, I, NIL) != OK)
00084 return NOTOK;
00085 if (_InitializeIsolatorContext (theGraph) != OK)
00086 return NOTOK;
00087
00088
00089 if (theGraph->IC.minorType & FLAGS_MINOR_A)
00090 RetVal = _IsolateMinorA (theGraph);
00091
00092 else if (theGraph->IC.minorType & FLAGS_MINOR_B)
00093 RetVal = _IsolateMinorB (theGraph);
00094
00095 else if (theGraph->IC.minorType & FLAGS_MINOR_C)
00096 RetVal = _IsolateMinorC (theGraph);
00097
00098 else if (theGraph->IC.minorType & FLAGS_MINOR_D)
00099 RetVal = _IsolateMinorD (theGraph);
00100
00101 else if (theGraph->IC.minorType & FLAGS_MINOR_E)
00102 RetVal = _IsolateMinorE (theGraph);
00103
00104
00105 if (RetVal == OK)
00106 RetVal = _DeleteUnmarkedVerticesAndEdges (theGraph);
00107 return RetVal;
00108 }
00109
00110
00111
00112
00113
00114 int _InitializeIsolatorContext (graphP theGraph)
00115 {
00116 isolatorContextP IC = &theGraph->IC;
00117
00118
00119 if (_FindUnembeddedEdgeToAncestor (theGraph, IC->x, &IC->ux, &IC->dx) !=
00120 OK || _FindUnembeddedEdgeToAncestor (theGraph, IC->y, &IC->uy,
00121 &IC->dy) != OK)
00122 return NOTOK;
00123
00124
00125
00126
00127
00128 if (theGraph->IC.minorType & FLAGS_MINOR_B)
00129
00130 {
00131 int SubtreeRoot =
00132 LCGetPrev (theGraph->BicompLists, theGraph->V[IC->w].pertinentBicompList,
00133 NIL);
00134 IC->uz = theGraph->V[SubtreeRoot].Lowpoint;
00135 if (_FindUnembeddedEdgeToSubtree (theGraph, IC->v, SubtreeRoot, &IC->dw)
00136 != OK
00137 || _FindUnembeddedEdgeToSubtree (theGraph, IC->uz, SubtreeRoot,
00138 &IC->dz) != OK)
00139 return NOTOK;
00140 }
00141
00142
00143
00144 else
00145
00146 {
00147 if (_FindUnembeddedEdgeToCurVertex (theGraph, IC->w, &IC->dw) != OK)
00148 return NOTOK;
00149 if (theGraph->IC.minorType & FLAGS_MINOR_E)
00150 if (_FindUnembeddedEdgeToAncestor (theGraph, IC->z, &IC->uz, &IC->dz) !=
00151 OK)
00152 return NOTOK;
00153 }
00154 return OK;
00155 }
00156
00157
00158
00159
00160
00161 int _IsolateMinorA (graphP theGraph)
00162 {
00163 isolatorContextP IC = &theGraph->IC;
00164 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, IC->r) != OK
00165 || _MarkDFSPath (theGraph, MIN (IC->ux, IC->uy), IC->r) != OK
00166 || _MarkDFSPathsToDescendants (theGraph) != OK
00167 || _JoinBicomps (theGraph) != OK
00168 || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00169 return NOTOK;
00170 return OK;
00171 }
00172
00173
00174
00175
00176
00177 int _IsolateMinorB (graphP theGraph)
00178 {
00179 isolatorContextP IC = &theGraph->IC;
00180 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, IC->r) != OK
00181 || _MarkDFSPath (theGraph, MIN3 (IC->ux, IC->uy, IC->uz),
00182 MAX3 (IC->ux, IC->uy,
00183 IC->uz)) !=
00184 OK || _MarkDFSPathsToDescendants (theGraph) !=
00185 OK || _JoinBicomps (theGraph) !=
00186 OK || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00187 return NOTOK;
00188 return OK;
00189 }
00190
00191
00192
00193
00194
00195 int _IsolateMinorC (graphP theGraph)
00196 {
00197 isolatorContextP IC = &theGraph->IC;
00198 if (theGraph->G[IC->px].type == VERTEX_HIGH_RXW)
00199
00200 {
00201 int highY = theGraph->G[IC->py].type == VERTEX_HIGH_RYW ? IC->py : IC->y;
00202 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, highY) != OK)
00203 return NOTOK;
00204 }
00205
00206 else
00207
00208 {
00209 if (_MarkPathAlongBicompExtFace (theGraph, IC->x, IC->r) != OK)
00210 return NOTOK;
00211 }
00212 if (_MarkDFSPathsToDescendants (theGraph) != OK
00213 || _MarkDFSPath (theGraph, MIN (IC->ux, IC->uy), IC->r) != OK
00214 || _JoinBicomps (theGraph) != OK
00215 || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00216 return NOTOK;
00217 return OK;
00218 }
00219
00220
00221
00222
00223
00224 int _IsolateMinorD (graphP theGraph)
00225 {
00226 isolatorContextP IC = &theGraph->IC;
00227 if (_MarkPathAlongBicompExtFace (theGraph, IC->x, IC->y) != OK
00228 || _MarkDFSPath (theGraph, MIN (IC->ux, IC->uy), IC->r) != OK
00229 || _MarkDFSPathsToDescendants (theGraph) != OK
00230 || _JoinBicomps (theGraph) != OK
00231 || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00232 return NOTOK;
00233 return OK;
00234 }
00235
00236
00237
00238
00239
00240 int _IsolateMinorE (graphP theGraph)
00241 {
00242 isolatorContextP IC = &theGraph->IC;
00243
00244
00245 if (IC->z != IC->w)
00246 return _IsolateMinorE1 (theGraph);
00247
00248
00249 if (IC->uz > MAX (IC->ux, IC->uy))
00250 return _IsolateMinorE2 (theGraph);
00251
00252
00253 if (IC->uz < MAX (IC->ux, IC->uy) && IC->ux != IC->uy)
00254 return _IsolateMinorE3 (theGraph);
00255
00256
00257
00258 else if (IC->x != IC->px || IC->y != IC->py)
00259 return _IsolateMinorE4 (theGraph);
00260
00261
00262 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, IC->r) != OK
00263 || _MarkDFSPath (theGraph, MIN3 (IC->ux, IC->uy, IC->uz), IC->r) != OK
00264 || _MarkDFSPathsToDescendants (theGraph) != OK
00265 || _JoinBicomps (theGraph) != OK
00266 || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00267 return NOTOK;
00268 return OK;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278 int _IsolateMinorE1 (graphP theGraph)
00279 {
00280 isolatorContextP IC = &theGraph->IC;
00281 if (theGraph->G[IC->z].type == VERTEX_LOW_RXW)
00282
00283 {
00284 theGraph->G[IC->px].type = VERTEX_HIGH_RXW;
00285 IC->x = IC->z;
00286 IC->ux = IC->uz;
00287 IC->dx = IC->dz;
00288 }
00289
00290 else if (theGraph->G[IC->z].type == VERTEX_LOW_RYW)
00291
00292 {
00293 theGraph->G[IC->py].type = VERTEX_HIGH_RYW;
00294 IC->y = IC->z;
00295 IC->uy = IC->uz;
00296 IC->dy = IC->dz;
00297 }
00298
00299 else
00300 return NOTOK;
00301 IC->z = IC->uz = IC->dz = NIL;
00302 theGraph->IC.minorType ^= FLAGS_MINOR_E;
00303 theGraph->IC.minorType |= (FLAGS_MINOR_C | FLAGS_MINOR_E1);
00304 return _IsolateMinorC (theGraph);
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314 int _IsolateMinorE2 (graphP theGraph)
00315 {
00316 isolatorContextP IC = &theGraph->IC;
00317 _FillVisitedFlags (theGraph, 0);
00318 IC->v = IC->uz;
00319 IC->dw = IC->dz;
00320 IC->z = IC->uz = IC->dz = NIL;
00321 theGraph->IC.minorType ^= FLAGS_MINOR_E;
00322 theGraph->IC.minorType |= (FLAGS_MINOR_A | FLAGS_MINOR_E2);
00323 return _IsolateMinorA (theGraph);
00324 }
00325
00326
00327
00328
00329
00330 int _IsolateMinorE3 (graphP theGraph)
00331 {
00332 isolatorContextP IC = &theGraph->IC;
00333 if (IC->ux < IC->uy)
00334
00335 {
00336 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, IC->px) != OK
00337 || _MarkPathAlongBicompExtFace (theGraph, IC->w, IC->y) != OK)
00338 return NOTOK;
00339 }
00340
00341 else
00342
00343 {
00344 if (_MarkPathAlongBicompExtFace (theGraph, IC->x, IC->w) != OK
00345 || _MarkPathAlongBicompExtFace (theGraph, IC->py, IC->r) != OK)
00346 return NOTOK;
00347 }
00348 if (_MarkDFSPath (theGraph, MIN3 (IC->ux, IC->uy, IC->uz), IC->r) != OK
00349 || _MarkDFSPathsToDescendants (theGraph) != OK
00350 || _JoinBicomps (theGraph) != OK
00351 || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00352 return NOTOK;
00353 theGraph->IC.minorType |= FLAGS_MINOR_E3;
00354 return OK;
00355 }
00356
00357
00358
00359
00360
00361 int _IsolateMinorE4 (graphP theGraph)
00362 {
00363 isolatorContextP IC = &theGraph->IC;
00364 if (IC->px != IC->x)
00365
00366 {
00367 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, IC->w) != OK
00368 || _MarkPathAlongBicompExtFace (theGraph, IC->py, IC->r) != OK)
00369 return NOTOK;
00370 }
00371
00372 else
00373
00374 {
00375 if (_MarkPathAlongBicompExtFace (theGraph, IC->r, IC->px) != OK
00376 || _MarkPathAlongBicompExtFace (theGraph, IC->w, IC->r) != OK)
00377 return NOTOK;
00378 }
00379 if (_MarkDFSPath
00380 (theGraph, MIN3 (IC->ux, IC->uy, IC->uz),
00381 MAX3 (IC->ux, IC->uy,
00382 IC->uz)) != OK || _MarkDFSPathsToDescendants (theGraph) !=
00383 OK || _JoinBicomps (theGraph) !=
00384 OK || _AddAndMarkUnembeddedEdges (theGraph) != OK)
00385 return NOTOK;
00386 theGraph->IC.minorType |= FLAGS_MINOR_E4;
00387 return OK;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 int _GetLeastAncestorConnection (graphP theGraph,
00402 int cutVertex)
00403 {
00404 int subtreeRoot = theGraph->V[cutVertex].separatedDFSChildList;
00405 int ancestor = theGraph->V[cutVertex].leastAncestor;
00406 if (subtreeRoot != NIL && ancestor > theGraph->V[subtreeRoot].Lowpoint)
00407 ancestor = theGraph->V[subtreeRoot].Lowpoint;
00408 return ancestor;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 int _FindUnembeddedEdgeToAncestor (graphP theGraph,
00425 int cutVertex,
00426 int *pAncestor,
00427 int *pDescendant)
00428 {
00429 *pAncestor = _GetLeastAncestorConnection (theGraph, cutVertex);
00430 if (*pAncestor == theGraph->V[cutVertex].leastAncestor)
00431
00432 {
00433 *pDescendant = cutVertex;
00434 return OK;
00435 }
00436
00437 else
00438
00439 {
00440 int subtreeRoot = theGraph->V[cutVertex].separatedDFSChildList;
00441 return _FindUnembeddedEdgeToSubtree (theGraph, *pAncestor, subtreeRoot,
00442 pDescendant);
00443 }
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 int _FindUnembeddedEdgeToCurVertex (graphP theGraph,
00455 int cutVertex,
00456 int *pDescendant)
00457 {
00458 int RetVal = OK,
00459 I = theGraph->IC.v;
00460 if (theGraph->V[cutVertex].adjacentTo != NIL)
00461 *pDescendant = cutVertex;
00462
00463 else
00464
00465 {
00466 int subtreeRoot = theGraph->V[cutVertex].pertinentBicompList;
00467 RetVal =
00468 _FindUnembeddedEdgeToSubtree (theGraph, I, subtreeRoot, pDescendant);
00469 }
00470 return RetVal;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 int _FindUnembeddedEdgeToSubtree (graphP theGraph,
00482 int ancestor,
00483 int SubtreeRoot,
00484 int *pDescendant)
00485 {
00486 int J,
00487 Z,
00488 ZNew;
00489 *pDescendant = NIL;
00490
00491
00492
00493 if (SubtreeRoot >= theGraph->N)
00494 SubtreeRoot -= theGraph->N;
00495
00496
00497 J = theGraph->V[ancestor].fwdArcList;
00498 while (J != NIL)
00499
00500 {
00501 if (theGraph->G[J].v >= SubtreeRoot)
00502
00503 {
00504 if (*pDescendant == NIL || *pDescendant > theGraph->G[J].v)
00505 *pDescendant = theGraph->G[J].v;
00506 }
00507 J = theGraph->G[J].link[0];
00508 if (J == theGraph->V[ancestor].fwdArcList)
00509 J = NIL;
00510 }
00511 if (*pDescendant == NIL)
00512 return NOTOK;
00513
00514
00515 Z = *pDescendant;
00516 while (Z != SubtreeRoot)
00517
00518 {
00519 ZNew = theGraph->V[Z].DFSParent;
00520 if (ZNew == NIL || ZNew == Z)
00521 return NOTOK;
00522 Z = ZNew;
00523 }
00524
00525
00526 return OK;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 int _MarkPathAlongBicompExtFace (graphP theGraph,
00538 int startVert,
00539 int endVert)
00540 {
00541 int Z,
00542 ZPrevLink,
00543 ZPrevArc;
00544
00545
00546 theGraph->G[startVert].visited = 1;
00547
00548
00549
00550 Z = startVert;
00551
00552 do
00553
00554 {
00555 ZPrevLink = 1;
00556 Z = _GetNextVertexOnExternalFace (theGraph, Z, &ZPrevLink);
00557 ZPrevArc = theGraph->G[Z].link[ZPrevLink];
00558 theGraph->G[ZPrevArc].visited = 1;
00559 theGraph->G[gp_GetTwinArc (theGraph, ZPrevArc)].visited = 1;
00560 theGraph->G[Z].visited = 1;
00561 } while (Z != endVert);
00562 return OK;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 int _MarkDFSPath (graphP theGraph,
00580 int ancestor,
00581 int descendant)
00582 {
00583 int J,
00584 parent,
00585 Z,
00586 N;
00587 N = theGraph->N;
00588
00589
00590
00591 if (descendant >= N)
00592 descendant = theGraph->V[descendant - N].DFSParent;
00593
00594
00595 theGraph->G[descendant].visited = 1;
00596
00597
00598
00599 while (descendant != ancestor)
00600
00601 {
00602
00603
00604 parent = theGraph->V[descendant].DFSParent;
00605
00606
00607
00608 if (parent == NIL || parent == descendant)
00609 return NOTOK;
00610
00611
00612
00613
00614 J = theGraph->G[descendant].link[0];
00615 while (J >= 2 * theGraph->N)
00616
00617 {
00618 Z = theGraph->G[J].v;
00619
00620
00621
00622
00623
00624 if ((Z < N && Z == parent) ||
00625 (Z >= N && theGraph->V[Z - N].DFSParent == parent))
00626
00627 {
00628 theGraph->G[J].visited = 1;
00629 theGraph->G[gp_GetTwinArc (theGraph, J)].visited = 1;
00630 break;
00631 }
00632 J = theGraph->G[J].link[0];
00633 }
00634
00635
00636 theGraph->G[parent].visited = 1;
00637
00638
00639 descendant = parent;
00640 }
00641 return OK;
00642 }
00643
00644
00645
00646
00647
00648 int _MarkDFSPathsToDescendants (graphP theGraph)
00649 {
00650 isolatorContextP IC = &theGraph->IC;
00651 if (_MarkDFSPath (theGraph, IC->x, IC->dx) != OK
00652 || _MarkDFSPath (theGraph, IC->y, IC->dy) != OK)
00653 return NOTOK;
00654 if (IC->dw != NIL)
00655 if (_MarkDFSPath (theGraph, IC->w, IC->dw) != OK)
00656 return NOTOK;
00657 if (IC->dz != NIL)
00658 if (_MarkDFSPath (theGraph, IC->w, IC->dz) != OK)
00659 return NOTOK;
00660 return OK;
00661 }
00662
00663
00664
00665
00666
00667 int _AddAndMarkUnembeddedEdges (graphP theGraph)
00668 {
00669 isolatorContextP IC = &theGraph->IC;
00670 if (_AddAndMarkEdge (theGraph, IC->ux, IC->dx) != OK
00671 || _AddAndMarkEdge (theGraph, IC->uy, IC->dy) != OK)
00672 return NOTOK;
00673 if (IC->dw != NIL)
00674 if (_AddAndMarkEdge (theGraph, IC->v, IC->dw) != OK)
00675 return NOTOK;
00676 if (IC->dz != NIL)
00677 if (_AddAndMarkEdge (theGraph, IC->uz, IC->dz) != OK)
00678 return NOTOK;
00679 return OK;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689 int _AddAndMarkEdge (graphP theGraph,
00690 int ancestor,
00691 int descendant)
00692 {
00693 _AddBackEdge (theGraph, ancestor, descendant);
00694
00695
00696 theGraph->G[ancestor].visited = 1;
00697 theGraph->G[theGraph->G[ancestor].link[0]].visited = 1;
00698 theGraph->G[theGraph->G[descendant].link[0]].visited = 1;
00699 theGraph->G[descendant].visited = 1;
00700 return OK;
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 void _AddBackEdge (graphP theGraph,
00712 int ancestor,
00713 int descendant)
00714 {
00715 int fwdArc,
00716 backArc;
00717
00718
00719 fwdArc = theGraph->V[ancestor].fwdArcList;
00720 while (fwdArc != NIL)
00721
00722 {
00723 if (theGraph->G[fwdArc].v == descendant)
00724 break;
00725 fwdArc = theGraph->G[fwdArc].link[0];
00726 if (fwdArc == theGraph->V[ancestor].fwdArcList)
00727 fwdArc = NIL;
00728 }
00729 if (fwdArc == NIL)
00730 return;
00731 backArc = gp_GetTwinArc (theGraph, fwdArc);
00732
00733
00734 if (theGraph->V[ancestor].fwdArcList == fwdArc)
00735
00736 {
00737 if (theGraph->G[fwdArc].link[0] == fwdArc)
00738 theGraph->V[ancestor].fwdArcList = NIL;
00739
00740 else
00741 theGraph->V[ancestor].fwdArcList = theGraph->G[fwdArc].link[0];
00742 }
00743 theGraph->G[theGraph->G[fwdArc].link[0]].link[1] =
00744 theGraph->G[fwdArc].link[1];
00745 theGraph->G[theGraph->G[fwdArc].link[1]].link[0] =
00746 theGraph->G[fwdArc].link[0];
00747
00748
00749 theGraph->G[fwdArc].link[1] = ancestor;
00750 theGraph->G[fwdArc].link[0] = theGraph->G[ancestor].link[0];
00751 theGraph->G[theGraph->G[ancestor].link[0]].link[1] = fwdArc;
00752 theGraph->G[ancestor].link[0] = fwdArc;
00753
00754
00755 theGraph->G[backArc].v = ancestor;
00756 theGraph->G[backArc].link[1] = descendant;
00757 theGraph->G[backArc].link[0] = theGraph->G[descendant].link[0];
00758 theGraph->G[theGraph->G[descendant].link[0]].link[1] = backArc;
00759 theGraph->G[descendant].link[0] = backArc;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768 int _DeleteUnmarkedVerticesAndEdges (graphP theGraph)
00769 {
00770 int I,
00771 J,
00772 fwdArc,
00773 descendant;
00774
00775
00776
00777
00778
00779 for (I = 0; I < theGraph->N; I++)
00780
00781 {
00782 while (theGraph->V[I].fwdArcList != NIL)
00783
00784 {
00785 fwdArc = theGraph->V[I].fwdArcList;
00786 descendant = theGraph->G[fwdArc].v;
00787 _AddBackEdge (theGraph, I, descendant);
00788 }
00789 }
00790
00791
00792
00793
00794 for (I = 0; I < theGraph->N; I++)
00795
00796 {
00797 J = theGraph->G[I].link[0];
00798 while (J >= 2 * theGraph->N)
00799
00800 {
00801 if (theGraph->G[J].visited)
00802 J = theGraph->G[J].link[0];
00803
00804 else
00805 J = gp_DeleteEdge (theGraph, J, 0);
00806 }
00807 }
00808 return OK;
00809 }