int _IsolateOuterplanarObstruction(graphP theGraph, int v, int R) { int RetVal; /* A subgraph homeomorphic to K_{2,3} or K_4 will be isolated by using the visited flags, set=keep edge/vertex and clear=omit. Here we initialize to omit all, then we subsequently set visited on all edges and vertices in the homeomorph. */ _ClearVisitedFlags(theGraph); /* Next we determineg which of the non-outerplanarity Minors was encountered and the principal bicomp on which the isolator will focus attention. */ if (_ChooseTypeOfNonOuterplanarityMinor(theGraph, v, R) != OK) return NOTOK; /* Find the path connecting the pertinent vertex w with the current vertex v */ if (theGraph->IC.minorType & MINORTYPE_B) { isolatorContextP IC = &theGraph->IC; int SubtreeRoot = gp_GetVertexLastPertinentRootChild(theGraph, IC->w); if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE) return NOTOK; } else { isolatorContextP IC = &theGraph->IC; if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; } /* For minor E, we need to find and mark an X-Y path */ if (theGraph->IC.minorType & MINORTYPE_E) { if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; } /* Call the appropriate isolator */ if (theGraph->IC.minorType & MINORTYPE_A) RetVal = _IsolateOuterplanarityObstructionA(theGraph); else if (theGraph->IC.minorType & MINORTYPE_B) RetVal = _IsolateOuterplanarityObstructionB(theGraph); else if (theGraph->IC.minorType & MINORTYPE_E) RetVal = _IsolateOuterplanarityObstructionE(theGraph); else RetVal = NOTOK; /* Delete the unmarked edges and vertices, and return */ if (RetVal == OK) RetVal = _DeleteUnmarkedVerticesAndEdges(theGraph); return RetVal; }
int _FindUnembeddedEdgeToAncestor(graphP theGraph, int cutVertex, int *pAncestor, int *pDescendant) { int child, foundChild; int ancestor = gp_GetVertexLeastAncestor(theGraph, cutVertex); child = gp_GetVertexFuturePertinentChild(theGraph, cutVertex); foundChild = NIL; while (gp_IsVertex(child)) { if (gp_IsSeparatedDFSChild(theGraph, child) && ancestor > gp_GetVertexLowpoint(theGraph, child)) { ancestor = gp_GetVertexLowpoint(theGraph, child); foundChild = child; } child = gp_GetVertexNextDFSChild(theGraph, cutVertex, child); } *pAncestor = ancestor; // If the least ancestor connection was direct, then return the cutVertex as the descendant if (ancestor == gp_GetVertexLeastAncestor(theGraph, cutVertex)) { *pDescendant = cutVertex; return TRUE; } // Otherwise find the descendant based on the separated child with least lowpoint return _FindUnembeddedEdgeToSubtree(theGraph, *pAncestor, foundChild, pDescendant); }
int _InitializeIsolatorContext(graphP theGraph) { isolatorContextP IC = &theGraph->IC; /* Obtains the edges connecting X and Y to ancestors of the current vertex */ if (_FindUnembeddedEdgeToAncestor(theGraph, IC->x, &IC->ux, &IC->dx) != TRUE || _FindUnembeddedEdgeToAncestor(theGraph, IC->y, &IC->uy, &IC->dy) != TRUE) return NOTOK; /* For Minor B, we seek the last pertinent child biconnected component, which is also future pertinent, and obtain the DFS child in its root edge. This child is the subtree root containing vertices with connections to both the current vertex and an ancestor of the current vertex. */ if (theGraph->IC.minorType & MINORTYPE_B) { int SubtreeRoot = gp_GetVertexLastPertinentRootChild(theGraph, IC->w); IC->uz = gp_GetVertexLowpoint(theGraph, SubtreeRoot); if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE || _FindUnembeddedEdgeToSubtree(theGraph, IC->uz, SubtreeRoot, &IC->dz) != TRUE) return NOTOK; } /* For all other minors, we obtain an unembedded connecting the current vertex to the pertinent vertex W, and for minor E we collect the additional unembedded ancestor connection for the future pertinent vertex Z. */ else { if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (theGraph->IC.minorType & MINORTYPE_E) if (_FindUnembeddedEdgeToAncestor(theGraph, IC->z, &IC->uz, &IC->dz) != TRUE) return NOTOK; } return OK; }
int _InitializeIsolatorContext(graphP theGraph) { isolatorContextP IC = &theGraph->IC; /* Obtains the edges connecting X and Y to ancestors of the current vertex */ if (_FindUnembeddedEdgeToAncestor(theGraph, IC->x, &IC->ux, &IC->dx) != TRUE || _FindUnembeddedEdgeToAncestor(theGraph, IC->y, &IC->uy, &IC->dy) != TRUE) return NOTOK; /* For Minor B, we seek the last pertinent child biconnected component, which is externally active, and obtain the DFS child in its root edge. This child is the subtree root containing vertices with connections to both the current vertex and an ancestor of the current vertex. */ if (theGraph->IC.minorType & MINORTYPE_B) { int SubtreeRoot = LCGetPrev(theGraph->BicompLists, theGraph->V[IC->w].pertinentBicompList, NIL); IC->uz = theGraph->V[SubtreeRoot].Lowpoint; if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE || _FindUnembeddedEdgeToSubtree(theGraph, IC->uz, SubtreeRoot, &IC->dz) != TRUE) return NOTOK; } /* For all other minors, we obtain */ else { if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (theGraph->IC.minorType & MINORTYPE_E) if (_FindUnembeddedEdgeToAncestor(theGraph, IC->z, &IC->uz, &IC->dz) != TRUE) return NOTOK; } return OK; }
int _FindUnembeddedEdgeToCurVertex(graphP theGraph, int cutVertex, int *pDescendant) { if (gp_IsArc(gp_GetVertexPertinentEdge(theGraph, cutVertex))) { *pDescendant = cutVertex; return TRUE; } else { int subtreeRoot = gp_GetVertexFirstPertinentRootChild(theGraph, cutVertex); return _FindUnembeddedEdgeToSubtree(theGraph, theGraph->IC.v, subtreeRoot, pDescendant); } }
int _FindUnembeddedEdgeToCurVertex(graphP theGraph, int cutVertex, int *pDescendant) { int RetVal = TRUE, I = theGraph->IC.v; if (theGraph->V[cutVertex].adjacentTo != NIL) *pDescendant = cutVertex; else { int subtreeRoot = theGraph->V[cutVertex].pertinentBicompList; RetVal = _FindUnembeddedEdgeToSubtree(theGraph, I, subtreeRoot, pDescendant); } return RetVal; }
int _FindUnembeddedEdgeToAncestor(graphP theGraph, int cutVertex, int *pAncestor, int *pDescendant) { *pAncestor = _GetLeastAncestorConnection(theGraph, cutVertex); if (*pAncestor == theGraph->V[cutVertex].leastAncestor) { *pDescendant = cutVertex; return TRUE; } else { int subtreeRoot = theGraph->V[cutVertex].separatedDFSChildList; return _FindUnembeddedEdgeToSubtree(theGraph, *pAncestor, subtreeRoot, pDescendant); } }
int _SearchForK23InBicomp(graphP theGraph, int I, int R) { isolatorContextP IC = &theGraph->IC; int X, Y, XPrevLink, YPrevLink; /* Begin by determining whether minor A, B or E is detected */ if (_ChooseTypeOfNonOuterplanarityMinor(theGraph, I, R) != OK) return NOTOK; /* Minors A and B result in the desired K_{2,3} homeomorph, so we isolate it and return NONEMBEDDABLE. */ if (theGraph->IC.minorType & (MINORTYPE_A|MINORTYPE_B)) { _FillVisitedFlags(theGraph, 0); if (theGraph->IC.minorType & MINORTYPE_A) { if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (_IsolateOuterplanarityObstructionA(theGraph) != OK) return NOTOK; } else if (theGraph->IC.minorType & MINORTYPE_B) { int SubtreeRoot = LCGetPrev(theGraph->BicompLists, theGraph->V[IC->w].pertinentBicompList, NIL); if (_FindUnembeddedEdgeToSubtree(theGraph, IC->v, SubtreeRoot, &IC->dw) != TRUE) return NOTOK; if (_IsolateOuterplanarityObstructionB(theGraph) != OK) return NOTOK; } if (_DeleteUnmarkedVerticesAndEdges(theGraph) != OK) return NOTOK; return NONEMBEDDABLE; } /* For minor E (a K_4) , we run the additional tests to see if a K_{2,3} is entangled with the K_4. If not, then we return OK to indicate that the outerplanarity embedder should proceed as if the K_4 had not been found. */ /* If any vertices other than R, X, Y and W exist along the external face, then we can obtain a K_{2,3} by minor E1 or E2 */ X = IC->x; Y = IC->y; XPrevLink = 1; YPrevLink = 0; if (IC->w != _GetNextVertexOnExternalFace(theGraph, X, &XPrevLink) || IC->w != _GetNextVertexOnExternalFace(theGraph, Y, &YPrevLink)) { _FillVisitedFlags(theGraph, 0); if (_IsolateOuterplanarityObstructionE1orE2(theGraph) != OK) return NOTOK; if (_DeleteUnmarkedVerticesAndEdges(theGraph) != OK) return NOTOK; return NONEMBEDDABLE; } /* If X, Y or W make either a direct back edge connection or a connection through a separated child bicomp to an ancestor of the current vertex I, then we can obtain a K_{2,3} by minor E3 or E4. Note that this question is query on X, Y and W is equivalent to the planarity version of external activity. */ if (FUTUREPERTINENT(theGraph, X, I) || FUTUREPERTINENT(theGraph, Y, I) || FUTUREPERTINENT(theGraph, IC->w, I)) { _FillVisitedFlags(theGraph, 0); if (_IsolateOuterplanarityObstructionE3orE4(theGraph) != OK) return NOTOK; if (_DeleteUnmarkedVerticesAndEdges(theGraph) != OK) return NOTOK; return NONEMBEDDABLE; } /* The extra cases for finding a K_{2,3} failed, so the bicomp rooted by R is a separable subgraph of the input that is isomorphic to K_4. So, we restore the original vertex orientation of the bicomp (because it's polite, not because we really have to). Then, we return OK to tell the outerplanarity embedder that it can ignore this K_4 and keep processing. */ if (_OrientVerticesInBicomp(theGraph, R, 1) != OK) return NOTOK; return OK; }