/**************************************************************************** _MarkDFSPath() Sets visited flags of vertices and edges from descendant to ancestor, including root copy vertices, and including the step of hopping from a root copy to its parent copy. At each vertex, the edge record is obtained whose type indicates that it leads to the DFS parent. An earlier implementation just used the DFS parent member of the vertex, but then had to find the edge to mark anyway. This method is more generalized because some extension algorithms reduce DFS paths to single DFS tree edges, in which case the edge record with type EDGE_TYPE_PARENT may indicate the DFS paent or an ancestor. ****************************************************************************/ int _MarkDFSPath(graphP theGraph, int ancestor, int descendant) { int e, parent; // If we are marking from a root (virtual) vertex upward, then go up to the parent // copy before starting the loop if (gp_IsVirtualVertex(theGraph, descendant)) descendant = gp_GetPrimaryVertexFromRoot(theGraph, descendant); // Mark the lowest vertex (the one with the highest number). gp_SetVertexVisited(theGraph, descendant); // Mark all ancestors of the lowest vertex, and the edges used to reach // them, up to the given ancestor vertex. while (descendant != ancestor) { if (gp_IsNotVertex(descendant)) return NOTOK; // If we are at a bicomp root, then ascend to its parent copy and // mark it as visited. if (gp_IsVirtualVertex(theGraph, descendant)) { parent = gp_GetPrimaryVertexFromRoot(theGraph, descendant); } // If we are on a regular, non-virtual vertex then get the edge to the parent, // mark the edge, then fall through to the code that marks the parent vertex. else { // Scan the edges for the one marked as the DFS parent parent = NIL; e = gp_GetFirstArc(theGraph, descendant); while (gp_IsArc(e)) { if (gp_GetEdgeType(theGraph, e) == EDGE_TYPE_PARENT) { parent = gp_GetNeighbor(theGraph, e); break; } e = gp_GetNextArc(theGraph, e); } // Sanity check on the data structure integrity if (gp_IsNotVertex(parent)) return NOTOK; // Mark the edge gp_SetEdgeVisited(theGraph, e); gp_SetEdgeVisited(theGraph, gp_GetTwinArc(theGraph, e)); } // Mark the parent, then hop to the parent and reiterate gp_SetVertexVisited(theGraph, parent); descendant = parent; } return OK; }
int _ChooseTypeOfNonOuterplanarityMinor(graphP theGraph, int v, int R) { int X, Y, W; // Create the initial non-outerplanarity obstruction isolator state. if (_InitializeNonplanarityContext(theGraph, v, R) != OK) return NOTOK; 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 v, // then the Walkdown terminated on a descendant bicomp, which is Minor A. if (gp_GetPrimaryVertexFromRoot(theGraph, R) != v) { theGraph->IC.minorType |= MINORTYPE_A; return OK; } // If W has a pertinent child bicomp, then we've found Minor B. // Notice this is different from planarity, in which minor B is indicated // only if the pertinent child bicomp is also future pertinent. if (gp_IsVertex(gp_GetVertexPertinentRootsList(theGraph, W))) { theGraph->IC.minorType |= MINORTYPE_B; return OK; } // The only other result is minor E (we will search for the X-Y path later) theGraph->IC.minorType |= MINORTYPE_E; return OK; }