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 _IsolateOuterplanarityObstructionE3orE4(graphP theGraph) { isolatorContextP IC = &theGraph->IC; int u, d, XorY; /* Minor E3 */ if (FUTUREPERTINENT(theGraph, theGraph->IC.x, theGraph->IC.v) || FUTUREPERTINENT(theGraph, theGraph->IC.y, theGraph->IC.v)) { if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; if (FUTUREPERTINENT(theGraph, theGraph->IC.x, theGraph->IC.v)) XorY = theGraph->IC.x; else XorY = theGraph->IC.y; /* The cases of X externally active and Y externally active are the same except for the bicomp external face marking (because parameter order is important) */ if (XorY == theGraph->IC.x) { if (_MarkPathAlongBicompExtFace(theGraph, IC->x, IC->w) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->y, IC->r) != OK) return NOTOK; } else { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->x) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->w, IC->y) != OK) return NOTOK; } if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE) return NOTOK; if (_FindUnembeddedEdgeToAncestor(theGraph, XorY, &u, &d) != TRUE) return NOTOK; if (theGraph->functions.fpMarkDFSPath(theGraph, u, IC->v) != OK || theGraph->functions.fpMarkDFSPath(theGraph, XorY, d) != OK || theGraph->functions.fpMarkDFSPath(theGraph, IC->w, IC->dw) != OK || _JoinBicomps(theGraph) != OK || _AddAndMarkEdge(theGraph, u, d) != OK || _AddAndMarkEdge(theGraph, IC->v, IC->dw) != OK) return NOTOK; return OK; } /* Otherwise, isolate Minor E4 (reduce to minor A) */ if (_FindUnembeddedEdgeToAncestor(theGraph, IC->w, &u, &d) != TRUE) return NOTOK; IC->v = u; IC->dw = d; return _IsolateOuterplanarityObstructionA(theGraph); }
int _IsolateOuterplanarityObstructionE1orE2(graphP theGraph) { isolatorContextP IC = &theGraph->IC; int XPrevLink = 1; if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; /* Isolate E1 */ if (theGraph->IC.px != theGraph->IC.x) { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->w) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->py, IC->r) != OK) return NOTOK; } else if (theGraph->IC.py != theGraph->IC.y) { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->x) != OK || _MarkPathAlongBicompExtFace(theGraph, IC->w, IC->r) != OK) return NOTOK; } /* Isolate E2 */ else if (IC->w != _GetNextVertexOnExternalFace(theGraph, IC->x, &XPrevLink)) { if (_MarkPathAlongBicompExtFace(theGraph, IC->r, IC->y) != OK) return NOTOK; } else { if (_MarkPathAlongBicompExtFace(theGraph, IC->x, IC->r) != OK) return NOTOK; } /* Final bits are in common */ if (_FindUnembeddedEdgeToCurVertex(theGraph, IC->w, &IC->dw) != TRUE || theGraph->functions.fpMarkDFSPath(theGraph, IC->w, IC->dw) != OK || _JoinBicomps(theGraph) != OK || _AddAndMarkEdge(theGraph, IC->v, IC->dw) != OK) return NOTOK; return OK; }
int _ChooseTypeOfNonplanarityMinor(graphP theGraph, int I, int R) { int N, X, Y, W, Px, Py, Z, DFSChild, RootId; /* Create the initial non-planarity minor state in the isolator context */ if (_InitializeNonplanarityContext(theGraph, I, R) != OK) return NOTOK; N = theGraph->N; R = theGraph->IC.r; X = theGraph->IC.x; Y = theGraph->IC.y; W = theGraph->IC.w; /* If the root copy is not a root copy of the current vertex I, then the Walkdown terminated because it couldn't find a viable path along a child bicomp, which is Minor A. */ if (theGraph->V[R - N].DFSParent != I) { theGraph->IC.minorType |= MINORTYPE_A; return OK; } /* If W has an externally active pertinent child bicomp, then we've found Minor B */ if (theGraph->V[W].pertinentBicompList != NIL) { RootId = LCGetPrev(theGraph->BicompLists, theGraph->V[W].pertinentBicompList, NIL); DFSChild = RootId; if (theGraph->V[DFSChild].Lowpoint < I) { theGraph->IC.minorType |= MINORTYPE_B; return OK; } } /* Find the highest obstructing X-Y path */ if (_MarkHighestXYPath(theGraph) != TRUE) return NOTOK; Px = theGraph->IC.px; Py = theGraph->IC.py; /* If either point of attachment is 'high' (P_x closer to R than X or P_y closer to R than Y along external face), then we've matched Minor C. */ if (theGraph->G[Px].type == VERTEX_HIGH_RXW || theGraph->G[Py].type == VERTEX_HIGH_RYW) { theGraph->IC.minorType |= MINORTYPE_C; return OK; } /* For Minor D, we search for a path from an internal vertex Z along the X-Y path up to the root R of the bicomp. */ if (_MarkZtoRPath(theGraph) != OK) return NOTOK; if (theGraph->IC.z != NIL) { theGraph->IC.minorType |= MINORTYPE_D; return OK; } /* For Minor E, we search for an externally active vertex Z below the points of attachment of the X-Y path */ Z = _FindExtActivityBelowXYPath(theGraph); if (Z != NIL) { theGraph->IC.z = Z; theGraph->IC.minorType |= MINORTYPE_E; return OK; } return NOTOK; }