SList<node>& DynamicSPQRForest::findPathSPQR (node sH, node tH, node& rT) const { SList<node>& pT = *OGDF_NEW SList<node>; node sT = spqrproper(sH->firstAdj()->theEdge()); node tT = spqrproper(tH->firstAdj()->theEdge()); node nT = findNCASPQR(sT,tT); while (sT!=nT) { edge eH = m_tNode_hRefEdge[sT]; node uH = eH->source(); node vH = eH->target(); if (uH!=sH && vH!=sH) pT.pushBack(sT); if (uH==tH || vH==tH) { rT = sT; return pT; } sT = spqrproper(m_hEdge_twinEdge[eH]); } SListIterator<node> iT = pT.rbegin(); while (tT!=nT) { edge eH = m_tNode_hRefEdge[tT]; node uH = eH->source(); node vH = eH->target(); if (uH!=tH && vH!=tH) { if (iT.valid()) pT.insertAfter(tT,iT); else pT.pushFront(tT); } if (uH==sH || vH==sH) { rT = tT; return pT; } tT = spqrproper(m_hEdge_twinEdge[eH]); } if (iT.valid()) pT.insertAfter(nT,iT); else pT.pushFront(nT); rT = nT; return pT; }
node DynamicSPQRForest::findNCASPQR (node sT, node tT) const { if (m_tNode_isMarked[sT]) return sT; m_tNode_isMarked[sT] = true; node uT = m_tNode_hRefEdge[sT] ? spqrproper(m_hEdge_twinEdge[m_tNode_hRefEdge[sT]]) : 0; if (uT) uT = findNCASPQR(tT,uT); else for (uT=tT; !m_tNode_isMarked[uT]; uT=spqrproper(m_hEdge_twinEdge[m_tNode_hRefEdge[uT]])); m_tNode_isMarked[sT] = false; return uT; }
edge DynamicSPQRForest::virtualEdge (node vT, node wT) const { edge eH = m_tNode_hRefEdge[vT]; if (eH) { eH = m_hEdge_twinEdge[eH]; if (spqrproper(eH)==wT) return eH; } eH = m_tNode_hRefEdge[wT]; if (eH) { if (spqrproper(m_hEdge_twinEdge[eH])==vT) return eH; } return 0; }
node DynamicSPQRTree::updateInsertedNode(edge eG, edge fG) { edge eH = m_gEdge_hEdge[eG]; node vT = spqrproper(eH); if (m_tNode_type[vT] == SComp) { DynamicSPQRForest::updateInsertedNode(eG, fG); if (m_sk[vT]) { edge fH = m_gEdge_hEdge[fG]; edge fM = m_skelEdge[fH] = m_sk[vT]->getGraph().split(m_skelEdge[eH]); m_sk[vT]->m_origNode[fM->source()] = fH->source(); m_sk[vT]->m_origEdge[fM] = fH; } } else { DynamicSPQRForest::updateInsertedNode(eG, fG); if (m_sk[vT]) { edge gH = m_hEdge_twinEdge[m_tNode_hEdges[spqrproper(eH)].front()]; edge gM = m_skelEdge[gH] = m_skelEdge[eH]; m_sk[vT]->m_origEdge[gM] = gH; } } return fG->source(); }
node DynamicSPQRTree::rootTreeAt(node vT) { vT = findSPQR(vT); node uT = vT; edge eH = nullptr; for (;;) { edge fH = m_tNode_hRefEdge[uT]; m_tNode_hRefEdge[uT] = eH; if (!fH) break; eH = m_hEdge_twinEdge[fH]; uT = spqrproper(eH); } m_rootEdge = nullptr; return m_bNode_SPQR[m_B.firstNode()] = vT; }
edge DynamicSPQRForest::updateInsertedEdgeSPQR (node vB, edge eG) { node sG = eG->source(); node tG = eG->target(); node sH = repVertex(sG,vB); node tH = repVertex(tG,vB); edge eH = m_H.newEdge(sH,tH); m_gEdge_hEdge[eG] = eH; m_hEdge_gEdge[eH] = eG; adjEntry aH; forall_adj (aH,sH) { edge fH = aH->theEdge(); if (fH==eH) continue; if (fH->opposite(sH)!=tH) continue; node vT = spqrproper(fH); if (m_tNode_type[vT]==PComp) { m_hEdge_position[eH] = m_tNode_hEdges[vT].pushBack(eH); m_hEdge_tNode[eH] = vT; return eG; } edge gH = m_hEdge_twinEdge[fH]; if (!gH) { m_bNode_numP[vB]++; node nT = m_T.newNode(); m_tNode_type[nT] = PComp; m_tNode_owner[nT] = nT; edge v1 = m_H.newEdge(sH,tH); edge v2 = m_H.newEdge(sH,tH); m_hEdge_position[v1] = m_tNode_hEdges[vT].insertAfter(v1,m_hEdge_position[fH]); m_tNode_hEdges[vT].del(m_hEdge_position[fH]); m_hEdge_position[v2] = m_tNode_hEdges[nT].pushBack(v2); m_hEdge_position[fH] = m_tNode_hEdges[nT].pushBack(fH); m_hEdge_position[eH] = m_tNode_hEdges[nT].pushBack(eH); m_hEdge_tNode[v1] = vT; m_hEdge_twinEdge[v1] = m_tNode_hRefEdge[nT] = v2; m_hEdge_tNode[v2] = m_hEdge_tNode[eH] = m_hEdge_tNode[fH] = nT; m_hEdge_twinEdge[v2] = v1; return eG; } node wT = spqrproper(gH); if (m_tNode_type[wT]==PComp) { m_hEdge_position[eH] = m_tNode_hEdges[vT].pushBack(eH); m_hEdge_tNode[eH] = vT; } else { m_bNode_numP[vB]++; node nT = m_T.newNode(); m_tNode_type[nT] = PComp; m_tNode_owner[nT] = nT; edge v1 = m_tNode_hRefEdge[vT]; if (!v1) v1 = m_tNode_hRefEdge[wT]; else if (spqrproper(m_hEdge_twinEdge[v1])!=wT) v1 = m_tNode_hRefEdge[wT]; edge v4 = m_hEdge_twinEdge[v1]; edge v2 = m_H.newEdge(v1->source(),v1->target()); edge v3 = m_H.newEdge(v4->source(),v4->target()); m_hEdge_twinEdge[v1] = v2; m_hEdge_twinEdge[v2] = v1; m_hEdge_twinEdge[v3] = v4; m_hEdge_twinEdge[v4] = v3; m_hEdge_position[v2] = m_tNode_hEdges[nT].pushBack(v2); m_hEdge_position[eH] = m_tNode_hEdges[nT].pushBack(eH); m_hEdge_position[v3] = m_tNode_hEdges[nT].pushBack(v3); m_hEdge_tNode[v2] = m_hEdge_tNode[eH] = m_hEdge_tNode[v3] = nT; m_tNode_hRefEdge[nT] = v3; } return eG; }
edge DynamicSPQRTree::updateInsertedEdge(edge eG) { SList<node> marked; node sH = m_gNode_hNode[eG->source()]; node tH = m_gNode_hNode[eG->target()]; for (adjEntry aH : sH->adjEdges) { edge fH = aH->theEdge(); node vT = spqrproper(fH); if (fH->opposite(sH) == tH) { if (m_tNode_type[vT] == PComp) { DynamicSPQRForest::updateInsertedEdge(eG); if (m_sk[vT]) { edge eH = m_gEdge_hEdge[eG]; edge fM = m_skelEdge[fH]; node sM = fM->source(); node tM = fM->target(); if (eH->source() == m_sk[vT]->m_origNode[tM]) { node uM = sM; sM = tM; tM = uM; } m_skelEdge[eH] = m_sk[vT]->getGraph().newEdge(sM, tM); m_sk[vT]->m_origEdge[m_skelEdge[eH]] = eH; } return eG; } else if (!m_hEdge_twinEdge[fH]) { DynamicSPQRForest::updateInsertedEdge(eG); if (m_sk[vT]) { edge gH = m_hEdge_twinEdge[m_tNode_hEdges[m_hEdge_tNode[fH]].front()]; m_skelEdge[gH] = m_skelEdge[fH]; m_sk[vT]->m_origEdge[m_skelEdge[gH]] = gH; } return eG; } else { m_tNode_isMarked[vT] = true; marked.pushBack(vT); } } else { m_tNode_isMarked[vT] = true; marked.pushBack(vT); } } int count = 0; node found[2]; for (adjEntry aH : tH->adjEdges) { edge fH = aH->theEdge(); node vT = spqrproper(fH); if (!m_tNode_isMarked[vT]) continue; found[count++] = vT; m_tNode_isMarked[vT] = false; } while (!marked.empty()) m_tNode_isMarked[marked.popFrontRet()] = false; if (count == 0) { node rT; SList<node>& pT = findPathSPQR(sH, tH, rT); for (node vT : pT) { if (m_sk[vT]) { delete m_sk[vT]; m_sk[vT] = nullptr; } } delete &pT; } else if (count == 1) { node vT = found[0]; if (m_sk[vT]) { delete m_sk[vT]; m_sk[vT] = nullptr; } } return DynamicSPQRForest::updateInsertedEdge(eG); }
node DynamicSPQRTree::rootTreeAt(edge eG) { node vT = rootTreeAt(spqrproper(m_gEdge_hEdge[eG])); m_rootEdge = eG; return vT; }