00001
00002
00003
00004
00005
00006
00007 #define GRAPHSTRUCTURE_C
00008
00009 #include <stdlib.h>
00010
00011 #include "graph_boyer.h"
00012
00013
00014
00015
00016 void _InitGraphNode (graphP theGraph,
00017 int I);
00018 void _ClearIsolatorContext (graphP theGraph);
00019 void _FillVisitedFlags (graphP theGraph,
00020 int FillValue);
00021 void _FillVisitedFlagsInBicomp (graphP theGraph,
00022 int BicompRoot,
00023 int FillValue);
00024 void _FillVisitedFlagsInOtherBicomps (graphP theGraph,
00025 int BicompRoot,
00026 int FillValue);
00027 void _SetVertexTypeInBicomp (graphP theGraph,
00028 int BicompRoot,
00029 int theType);
00030
00031
00032
00033
00034 void _ClearGraph (graphP theGraph);
00035 void _InitVertexRec (graphP theGraph,
00036 int I);
00037 int _GetRandomNumber (int NMin,
00038 int NMax);
00039 void _AddArc (graphP theGraph,
00040 int u,
00041 int v,
00042 int arcPos,
00043 int link);
00044 void _HideArc (graphP theGraph,
00045 int arcPos);
00046
00047
00048
00049
00050
00051
00052 graphP gp_New ()
00053 {
00054 graphP theGraph = (graphP) malloc (sizeof (BM_graph));
00055 if (theGraph != NULL)
00056
00057 {
00058 theGraph->G = NULL;
00059 theGraph->V = NULL;
00060 theGraph->BicompLists = NULL;
00061 theGraph->DFSChildLists = NULL;
00062 theGraph->theStack = NULL;
00063 theGraph->buckets = NULL;
00064 theGraph->bin = NULL;
00065 theGraph->extFace = NULL;
00066 _ClearGraph (theGraph);
00067 }
00068 return theGraph;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 int gp_InitGraph (graphP theGraph,
00086 int N)
00087 {
00088 int I;
00089 _ClearGraph (theGraph);
00090
00091
00092 if ((theGraph->G =
00093 (graphNodeP) malloc ((2 + 2 * EDGE_LIMIT) * N *
00094 sizeof (graphNode))) == NULL || (theGraph->V =
00095 (vertexRecP)
00096 malloc (N *
00097 sizeof
00098 (vertexRec)))
00099 == NULL || (theGraph->BicompLists =
00100 LCNew (N)) == NULL || (theGraph->DFSChildLists =
00101 LCNew (N)) ==
00102 NULL || (theGraph->theStack =
00103 sp_New (2 * 2 * EDGE_LIMIT * N)) ==
00104 NULL || (theGraph->buckets =
00105 (int *) malloc (N * sizeof (int))) ==
00106 NULL || (theGraph->bin = LCNew (N)) == NULL || (theGraph->extFace =
00107 (extFaceLinkRecP)
00108 malloc (2 * N *
00109 sizeof
00110 (extFaceLinkRec)))
00111 == NULL || 0)
00112
00113 {
00114 _ClearGraph (theGraph);
00115 return NOTOK;
00116 }
00117
00118
00119 theGraph->N = N;
00120 for (I = 0; I < (2 + 2 * EDGE_LIMIT) * N; I++)
00121 _InitGraphNode (theGraph, I);
00122 for (I = 0; I < N; I++)
00123 _InitVertexRec (theGraph, I);
00124 for (I = 0; I < 2 * N; I++)
00125
00126 {
00127 theGraph->extFace[I].link[0] = theGraph->extFace[I].link[1] = NIL;
00128 theGraph->extFace[I].inversionFlag = 0;
00129 }
00130 return OK;
00131 }
00132
00133
00134
00135
00136
00137
00138 void _InitGraphNode (graphP theGraph,
00139 int I)
00140 {
00141 theGraph->G[I].id = NIL;
00142 theGraph->G[I].v = theGraph->G[I].link[0] = theGraph->G[I].link[1] = NIL;
00143 theGraph->G[I].visited = 0;
00144 theGraph->G[I].type = TYPE_UNKNOWN;
00145 theGraph->G[I].sign = 1;
00146 }
00147
00148
00149
00150
00151
00152
00153 void _InitVertexRec (graphP theGraph,
00154 int I)
00155 {
00156 theGraph->V[I].leastAncestor = theGraph->V[I].Lowpoint = I;
00157 theGraph->V[I].DFSParent = NIL;
00158 theGraph->V[I].adjacentTo = NIL;
00159 theGraph->V[I].pertinentBicompList = NIL;
00160 theGraph->V[I].separatedDFSChildList = NIL;
00161 theGraph->V[I].fwdArcList = NIL;
00162 }
00163
00164
00165
00166
00167
00168 void _ClearIsolatorContext (graphP theGraph)
00169 {
00170 isolatorContextP IC = &theGraph->IC;
00171 IC->minorType = 0;
00172 IC->v = IC->r = IC->x = IC->y = IC->w = IC->px = IC->py = IC->z = IC->ux =
00173 IC->dx = IC->uy = IC->dy = IC->dw = IC->uz = IC->dz = NIL;
00174 }
00175
00176
00177
00178
00179
00180 void _FillVisitedFlags (graphP theGraph,
00181 int FillValue)
00182 {
00183 int i,
00184 limit;
00185 for (i = 0, limit = 2 * (theGraph->N + theGraph->M); i < limit; i++)
00186 theGraph->G[i].visited = FillValue;
00187 }
00188
00189
00190
00191
00192
00193 void _FillVisitedFlagsInBicomp (graphP theGraph,
00194 int BicompRoot,
00195 int FillValue)
00196 {
00197 int V,
00198 J;
00199 sp_ClearStack (theGraph->theStack);
00200 sp_Push (theGraph->theStack, BicompRoot);
00201 while (sp_NonEmpty (theGraph->theStack))
00202
00203 {
00204 sp_Pop (theGraph->theStack, V);
00205 theGraph->G[V].visited = FillValue;
00206 J = theGraph->G[V].link[0];
00207 while (J >= 2 * theGraph->N)
00208
00209 {
00210 theGraph->G[J].visited = FillValue;
00211 if (theGraph->G[J].type == EDGE_DFSCHILD)
00212 sp_Push (theGraph->theStack, theGraph->G[J].v);
00213 J = theGraph->G[J].link[0];
00214 }
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 void _FillVisitedFlagsInOtherBicomps (graphP theGraph,
00232 int BicompRoot,
00233 int FillValue)
00234 {
00235 int R,
00236 N;
00237 N = theGraph->N;
00238 for (R = N; R < 2 * N; R++)
00239 if (theGraph->G[R].v != NIL && R != BicompRoot)
00240 _FillVisitedFlagsInBicomp (theGraph, R, FillValue);
00241 }
00242
00243
00244
00245
00246
00247 void _SetVertexTypeInBicomp (graphP theGraph,
00248 int BicompRoot,
00249 int theType)
00250 {
00251 int V,
00252 J;
00253 sp_ClearStack (theGraph->theStack);
00254 sp_Push (theGraph->theStack, BicompRoot);
00255 while (sp_NonEmpty (theGraph->theStack))
00256
00257 {
00258 sp_Pop (theGraph->theStack, V);
00259 theGraph->G[V].type = theType;
00260 J = theGraph->G[V].link[0];
00261 while (J >= 2 * theGraph->N)
00262
00263 {
00264 if (theGraph->G[J].type == EDGE_DFSCHILD)
00265 sp_Push (theGraph->theStack, theGraph->G[J].v);
00266 J = theGraph->G[J].link[0];
00267 }
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 void _ClearGraph (graphP theGraph)
00278 {
00279 if (theGraph->G != NULL)
00280
00281 {
00282 free (theGraph->G);
00283 theGraph->G = NULL;
00284 }
00285 if (theGraph->V != NULL)
00286
00287 {
00288 free (theGraph->V);
00289 theGraph->V = NULL;
00290 }
00291 theGraph->N = theGraph->M = 0;
00292 theGraph->internalFlags = theGraph->embedFlags = 0;
00293 _ClearIsolatorContext (theGraph);
00294 LCFree (&theGraph->BicompLists);
00295 LCFree (&theGraph->DFSChildLists);
00296 sp_Free (&theGraph->theStack);
00297 if (theGraph->buckets != NULL)
00298
00299 {
00300 free (theGraph->buckets);
00301 theGraph->buckets = NULL;
00302 }
00303 LCFree (&theGraph->bin);
00304 if (theGraph->extFace != NULL)
00305
00306 {
00307 free (theGraph->extFace);
00308 theGraph->extFace = NULL;
00309 }
00310 }
00311
00312
00313
00314
00315
00316
00317
00318 void gp_ReinitializeGraph (graphP theGraph)
00319 {
00320 int N = theGraph->N,
00321 I;
00322 theGraph->M = 0;
00323 theGraph->internalFlags = theGraph->embedFlags = 0;
00324 for (I = 0; I < (2 + 2 * EDGE_LIMIT) * N; I++)
00325 _InitGraphNode (theGraph, I);
00326 for (I = 0; I < N; I++)
00327 _InitVertexRec (theGraph, I);
00328 for (I = 0; I < 2 * N; I++)
00329
00330 {
00331 theGraph->extFace[I].link[0] = theGraph->extFace[I].link[1] = NIL;
00332 theGraph->extFace[I].inversionFlag = 0;
00333 }
00334 _ClearIsolatorContext (theGraph);
00335 LCReset (theGraph->BicompLists);
00336 LCReset (theGraph->DFSChildLists);
00337 sp_ClearStack (theGraph->theStack);
00338 LCReset (theGraph->bin);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347 void gp_Free (graphP * pGraph)
00348 {
00349 if (pGraph == NULL)
00350 return;
00351 if (*pGraph == NULL)
00352 return;
00353 _ClearGraph (*pGraph);
00354 free (*pGraph);
00355 *pGraph = NULL;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 int gp_CopyGraph (graphP dstGraph,
00368 graphP srcGraph)
00369 {
00370 int I;
00371
00372
00373 if (dstGraph == NULL || srcGraph == NULL)
00374 return NOTOK;
00375 if (dstGraph->N != srcGraph->N)
00376 return NOTOK;
00377 for (I = 0; I < (2 + 2 * EDGE_LIMIT) * srcGraph->N; I++)
00378 dstGraph->G[I] = srcGraph->G[I];
00379 for (I = 0; I < srcGraph->N; I++)
00380 dstGraph->V[I] = srcGraph->V[I];
00381 for (I = 0; I < 2 * srcGraph->N; I++)
00382
00383 {
00384 dstGraph->extFace[I].link[0] = srcGraph->extFace[I].link[0];
00385 dstGraph->extFace[I].link[1] = srcGraph->extFace[I].link[1];
00386 dstGraph->extFace[I].inversionFlag = srcGraph->extFace[I].inversionFlag;
00387 }
00388 dstGraph->N = srcGraph->N;
00389 dstGraph->M = srcGraph->M;
00390 dstGraph->internalFlags = srcGraph->internalFlags;
00391 dstGraph->embedFlags = srcGraph->embedFlags;
00392 dstGraph->IC = srcGraph->IC;
00393 LCCopy (dstGraph->BicompLists, srcGraph->BicompLists);
00394 LCCopy (dstGraph->DFSChildLists, srcGraph->DFSChildLists);
00395 sp_Copy (dstGraph->theStack, srcGraph->theStack);
00396 return OK;
00397 }
00398
00399
00400
00401
00402
00403 graphP gp_DupGraph (graphP theGraph)
00404 {
00405 graphP result;
00406 if ((result = gp_New ()) == NULL)
00407 return NULL;
00408 if (gp_InitGraph (result, theGraph->N) != OK
00409 || gp_CopyGraph (result, theGraph) != OK)
00410
00411 {
00412 gp_Free (&result);
00413 return NULL;
00414 }
00415 return result;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 int gp_CreateRandomGraph (graphP theGraph)
00430 {
00431 int N,
00432 I,
00433 M,
00434 u,
00435 v;
00436 N = theGraph->N;
00437
00438
00439
00440
00441
00442 for (I = 1; I < N; I++)
00443 if (gp_AddEdge (theGraph, _GetRandomNumber (0, I - 1), 0, I, 0) != OK)
00444 return NOTOK;
00445
00446
00447
00448
00449 M = _GetRandomNumber (7 * N / 8, EDGE_LIMIT * N);
00450 if (M > N * (N - 1) / 2)
00451 M = N * (N - 1) / 2;
00452 for (I = N - 1; I < M; I++)
00453
00454 {
00455 u = _GetRandomNumber (0, N - 2);
00456 v = _GetRandomNumber (u + 1, N - 1);
00457 if (gp_IsNeighbor (theGraph, u, v))
00458 I--;
00459
00460 else
00461
00462 {
00463 if (gp_AddEdge (theGraph, u, 0, v, 0) != OK)
00464 return NOTOK;
00465 }
00466 }
00467 return OK;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 int _GetRandomNumber (int NMin,
00483 int NMax)
00484 {
00485 int N = rand ();
00486 if (NMax < NMin)
00487 return NMin;
00488 N += ((N & 0xFFFF0000) >> 16);
00489 N += ((N & 0x0000FF00) >> 8);
00490
00491
00492 if (N < 0)
00493 N = -N;
00494 N %= (NMax - NMin + 1);
00495 return N + NMin;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 int _getUnprocessedChild (graphP theGraph,
00508 int parent)
00509 {
00510 int J = theGraph->G[parent].link[0];
00511 int JTwin = gp_GetTwinArc (theGraph, J);
00512 int child = theGraph->G[J].v;
00513
00514
00515
00516
00517
00518
00519 if (theGraph->G[J].type == TYPE_UNKNOWN)
00520 return NIL;
00521
00522
00523
00524
00525
00526 if (theGraph->G[J].visited)
00527 return NIL;
00528
00529
00530
00531
00532 theGraph->G[J].visited = 1;
00533 theGraph->G[JTwin].visited = 1;
00534
00535
00536
00537 if (theGraph->G[J].link[0] != theGraph->G[J].link[1])
00538
00539 {
00540 theGraph->G[parent].link[0] = theGraph->G[J].link[0];
00541 theGraph->G[theGraph->G[J].link[0]].link[1] = parent;
00542 theGraph->G[J].link[0] = parent;
00543 theGraph->G[J].link[1] = theGraph->G[parent].link[1];
00544 theGraph->G[theGraph->G[parent].link[1]].link[0] = J;
00545 theGraph->G[parent].link[1] = J;
00546 }
00547
00548
00549
00550 if (theGraph->G[J].link[0] != theGraph->G[J].link[1])
00551
00552 {
00553 theGraph->G[theGraph->G[JTwin].link[0]].link[1] =
00554 theGraph->G[JTwin].link[1];
00555 theGraph->G[theGraph->G[JTwin].link[1]].link[0] =
00556 theGraph->G[JTwin].link[0];
00557 theGraph->G[JTwin].link[0] = child;
00558 theGraph->G[JTwin].link[1] = theGraph->G[child].link[1];
00559 theGraph->G[theGraph->G[child].link[1]].link[0] = JTwin;
00560 theGraph->G[child].link[1] = JTwin;
00561 }
00562
00563
00564 theGraph->V[child].DFSParent = parent;
00565 return child;
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 int _hasUnprocessedChild (graphP theGraph,
00577 int parent)
00578 {
00579 int J = theGraph->G[parent].link[0];
00580 if (theGraph->G[J].type == TYPE_UNKNOWN)
00581 return 0;
00582 if (theGraph->G[J].visited)
00583 return 0;
00584 return 1;
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 int gp_CreateRandomGraphEx (graphP theGraph,
00600 int numEdges)
00601 {
00602
00603 #define EDGE_TREE_RANDOMGEN (TYPE_UNKNOWN+1)
00604 int N,
00605 I,
00606 arc,
00607 M,
00608 root,
00609 v,
00610 c,
00611 p,
00612 last,
00613 u,
00614 J,
00615 e;
00616 N = theGraph->N;
00617 if (numEdges > EDGE_LIMIT * N)
00618 numEdges = EDGE_LIMIT * N;
00619
00620
00621 for (I = 1; I < N; I++)
00622
00623 {
00624 v = _GetRandomNumber (0, I - 1);
00625 if (gp_AddEdge (theGraph, v, 0, I, 0) != OK)
00626 return NOTOK;
00627
00628 else
00629
00630 {
00631 arc = 2 * N + 2 * theGraph->M - 2;
00632 theGraph->G[arc].type = EDGE_TREE_RANDOMGEN;
00633 theGraph->G[gp_GetTwinArc (theGraph, arc)].type = EDGE_TREE_RANDOMGEN;
00634 theGraph->G[arc].visited = 0;
00635 theGraph->G[gp_GetTwinArc (theGraph, arc)].visited = 0;
00636 }
00637 }
00638
00639
00640 M = numEdges <= 3 * N - 6 ? numEdges : 3 * N - 6;
00641 root = 0;
00642 v = last = _getUnprocessedChild (theGraph, root);
00643 while (v != root && theGraph->M < M)
00644
00645 {
00646 c = _getUnprocessedChild (theGraph, v);
00647 if (c != NIL)
00648
00649 {
00650 if (last != v)
00651
00652 {
00653 if (gp_AddEdge (theGraph, last, 1, c, 1) != OK)
00654 return NOTOK;
00655 }
00656 if (gp_AddEdge (theGraph, root, 1, c, 1) != OK)
00657 return NOTOK;
00658 v = last = c;
00659 }
00660
00661 else
00662
00663 {
00664 p = theGraph->V[v].DFSParent;
00665 while (p != NIL && (c = _getUnprocessedChild (theGraph, p)) == NIL)
00666
00667 {
00668 v = p;
00669 p = theGraph->V[v].DFSParent;
00670 if (p != NIL && p != root)
00671
00672 {
00673 if (gp_AddEdge (theGraph, last, 1, p, 1) != OK)
00674 return NOTOK;
00675 }
00676 }
00677 if (p != NIL)
00678
00679 {
00680 if (p == root)
00681
00682 {
00683 if (gp_AddEdge (theGraph, v, 1, c, 1) != OK)
00684 return NOTOK;
00685 if (v != last)
00686
00687 {
00688 if (gp_AddEdge (theGraph, last, 1, c, 1) != OK)
00689 return NOTOK;
00690 }
00691 }
00692
00693 else
00694
00695 {
00696 if (gp_AddEdge (theGraph, last, 1, c, 1) != OK)
00697 return NOTOK;
00698 }
00699 if (p != root)
00700
00701 {
00702 if (gp_AddEdge (theGraph, root, 1, c, 1) != OK)
00703 return NOTOK;
00704 last = c;
00705 }
00706 v = c;
00707 }
00708 }
00709 }
00710
00711
00712 while (theGraph->M < numEdges)
00713
00714 {
00715 u = _GetRandomNumber (0, N - 1);
00716 v = _GetRandomNumber (0, N - 1);
00717 if (u != v && !gp_IsNeighbor (theGraph, u, v))
00718 if (gp_AddEdge (theGraph, u, 0, v, 0) != OK)
00719 return NOTOK;
00720 }
00721
00722
00723 for (e = 0; e < numEdges; e++)
00724
00725 {
00726 J = 2 * N + 2 * e;
00727 theGraph->G[J].type = TYPE_UNKNOWN;
00728 theGraph->G[gp_GetTwinArc (theGraph, J)].type = TYPE_UNKNOWN;
00729 theGraph->G[J].visited = 0;
00730 theGraph->G[gp_GetTwinArc (theGraph, J)].visited = 0;
00731 }
00732
00733
00734 for (I = 0; I < N; I++)
00735 theGraph->V[I].DFSParent = NIL;
00736 return OK;
00737
00738 #undef EDGE_TREE_RANDOMGEN
00739 }
00740
00741
00742
00743
00744
00745
00746
00747 int gp_IsNeighbor (graphP theGraph,
00748 int u,
00749 int v)
00750 {
00751 int J;
00752 J = theGraph->G[u].link[0];
00753 while (J >= 2 * theGraph->N)
00754
00755 {
00756 if (theGraph->G[J].v == v)
00757 return 1;
00758 J = theGraph->G[J].link[0];
00759 }
00760 return 0;
00761 }
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 int gp_GetVertexDegree (graphP theGraph,
00774 int v)
00775 {
00776 int J,
00777 degree;
00778 if (theGraph == NULL || v == NIL)
00779 return 0;
00780 degree = 0;
00781 J = theGraph->G[v].link[0];
00782 while (J >= 2 * theGraph->N)
00783
00784 {
00785 degree++;
00786 J = theGraph->G[J].link[0];
00787 }
00788 return degree;
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 void _AddArc (graphP theGraph,
00804 int u,
00805 int v,
00806 int arcPos,
00807 int link)
00808 {
00809 theGraph->G[arcPos].v = v;
00810 if (theGraph->G[u].link[0] == NIL)
00811
00812 {
00813 theGraph->G[u].link[0] = theGraph->G[u].link[1] = arcPos;
00814 theGraph->G[arcPos].link[0] = theGraph->G[arcPos].link[1] = u;
00815 }
00816
00817 else
00818
00819 {
00820 int u0 = theGraph->G[u].link[link];
00821 theGraph->G[arcPos].link[link] = u0;
00822 theGraph->G[arcPos].link[1 ^ link] = u;
00823 theGraph->G[u].link[link] = arcPos;
00824 theGraph->G[u0].link[1 ^ link] = arcPos;
00825 }
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 int gp_AddEdge (graphP theGraph,
00846 int u,
00847 int ulink,
00848 int v,
00849 int vlink)
00850 {
00851 int upos,
00852 vpos;
00853 if (theGraph == NULL || u < 0 || v < 0 || u >= 2 * theGraph->N
00854 || v >= 2 * theGraph->N)
00855 return NOTOK;
00856
00857
00858 if (theGraph->M >= EDGE_LIMIT * theGraph->N)
00859 return NONEMBEDDABLE;
00860 vpos = 2 * theGraph->N + 2 * theGraph->M;
00861 upos = gp_GetTwinArc (theGraph, vpos);
00862 _AddArc (theGraph, u, v, vpos, ulink);
00863 _AddArc (theGraph, v, u, upos, vlink);
00864 theGraph->M++;
00865 return OK;
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 void _HideArc (graphP theGraph,
00881 int arcPos)
00882 {
00883 int link0,
00884 link1;
00885 link0 = theGraph->G[arcPos].link[0];
00886 link1 = theGraph->G[arcPos].link[1];
00887 if (link0 == NIL || link1 == NIL)
00888 return;
00889 theGraph->G[link0].link[1] = link1;
00890 theGraph->G[link1].link[0] = link0;
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 void _RestoreArc (graphP theGraph,
00905 int arcPos)
00906 {
00907 int link0,
00908 link1;
00909 link0 = theGraph->G[arcPos].link[0];
00910 link1 = theGraph->G[arcPos].link[1];
00911 if (link0 == NIL || link1 == NIL)
00912 return;
00913 theGraph->G[link0].link[1] = arcPos;
00914 theGraph->G[link1].link[0] = arcPos;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 void gp_HideEdge (graphP theGraph,
00930 int arcPos)
00931 {
00932 _HideArc (theGraph, arcPos);
00933 _HideArc (theGraph, gp_GetTwinArc (theGraph, arcPos));
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 void gp_RestoreEdge (graphP theGraph,
00953 int arcPos)
00954 {
00955 _RestoreArc (theGraph, gp_GetTwinArc (theGraph, arcPos));
00956 _RestoreArc (theGraph, arcPos);
00957 }
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 int gp_DeleteEdge (graphP theGraph,
00971 int J,
00972 int nextLink)
00973 {
00974 int JTwin = gp_GetTwinArc (theGraph, J);
00975 int N = theGraph->N,
00976 M = theGraph->M;
00977 int nextArc,
00978 JPos,
00979 MPos,
00980 i;
00981
00982
00983
00984 nextArc = theGraph->G[J].link[nextLink];
00985
00986
00987 theGraph->G[theGraph->G[J].link[0]].link[1] = theGraph->G[J].link[1];
00988 theGraph->G[theGraph->G[J].link[1]].link[0] = theGraph->G[J].link[0];
00989 theGraph->G[theGraph->G[JTwin].link[0]].link[1] = theGraph->G[JTwin].link[1];
00990 theGraph->G[theGraph->G[JTwin].link[1]].link[0] = theGraph->G[JTwin].link[0];
00991
00992
00993
00994
00995
00996
00997
00998 JPos = (J < JTwin ? J : JTwin) - 2 * N;
00999 MPos = 2 * (M - 1);
01000 if (JPos < MPos)
01001
01002 {
01003 for (i = 0; i <= 1; i++, JPos++, MPos++)
01004
01005 {
01006 if (nextArc == 2 * N + MPos)
01007 nextArc = 2 * N + JPos;
01008 theGraph->G[2 * N + JPos] = theGraph->G[2 * N + MPos];
01009 theGraph->G[theGraph->G[2 * N + JPos].link[0]].link[1] = 2 * N + JPos;
01010 theGraph->G[theGraph->G[2 * N + JPos].link[1]].link[0] = 2 * N + JPos;
01011 }
01012 }
01013
01014
01015
01016 theGraph->M--;
01017 return nextArc;
01018 }