Open
Graph Drawing
Framework

 v.2012.05
 

SPQRTree.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046 
00047 
00048 #ifndef OGDF_SPQR_TREE_H
00049 #define OGDF_SPQR_TREE_H
00050 
00051 
00052 #include <ogdf/decomposition/Skeleton.h>
00053 #include <ogdf/decomposition/PertinentGraph.h>
00054 #include <ogdf/basic/SList.h>
00055 
00056 
00057 namespace ogdf {
00058 
00059 //---------------------------------------------------------
00060 // SPQRTree
00061 // SPQR-tree data structure
00062 //---------------------------------------------------------
00063 
00093 class OGDF_EXPORT SPQRTree
00094 {
00095 public:
00096 
00098     enum NodeType { SNode, PNode, RNode };
00099 
00100 
00101     // destructor
00102 
00103     virtual ~SPQRTree() { }
00104 
00105 
00106     //
00107     // a) Access operations
00108     //
00109 
00111     virtual const Graph &originalGraph() const=0;
00112 
00114     virtual const Graph &tree() const=0;
00115 
00117     virtual edge rootEdge() const=0;
00118 
00120     virtual node rootNode() const=0;
00121 
00123     virtual int numberOfSNodes() const=0;
00124 
00126     virtual int numberOfPNodes() const=0;
00127 
00129     virtual int numberOfRNodes() const=0;
00130 
00135     virtual NodeType typeOf(node v) const=0;
00136 
00138     virtual List<node> nodesOfType(NodeType t) const=0;
00139 
00144     virtual Skeleton &skeleton(node v) const=0;
00145 
00150     virtual const Skeleton &skeletonOfReal(edge e) const=0;
00151 
00156     virtual edge copyOfReal(edge e) const=0;
00157 
00162     void pertinentGraph(node v, PertinentGraph &Gp) const
00163     {
00164         if (m_cpV == 0) m_cpV = OGDF_NEW NodeArray<node>(originalGraph(),0);
00165         NodeArray<node> &cpV = *m_cpV;
00166 
00167         Gp.init(v);
00168         cpRec(v,Gp);
00169 
00170         const Skeleton &S = skeleton(v);
00171 
00172         edge e = Gp.m_skRefEdge = S.referenceEdge();
00173         if (e != 0) e = Gp.m_P.newEdge(cpV[S.original(e->source())],cpV[S.original(e->target())]);
00174         Gp.m_vEdge = e;
00175 
00176         while (!m_cpVAdded.empty()) cpV[m_cpVAdded.popFrontRet()] = 0;
00177     }
00178 
00179 
00180     //
00181     // b) Update operations
00182     //
00183 
00188     virtual node rootTreeAt(edge e) =0;
00189 
00194     virtual node rootTreeAt(node v) =0;
00195 
00196 
00197     void directSkEdge(node vT, edge e, node src)
00198     {
00199         OGDF_ASSERT(e != 0 && (src == e->source() || src == e->target()))
00200 
00201         if(e->source() != src) skeleton(vT).getGraph().reverseEdge(e);
00202     }
00203 
00204     void replaceSkEdgeByPeak(node vT, edge e)
00205     {
00206         Graph &M = skeleton(vT).getGraph();
00207         M.reverseEdge(M.split(e));
00208     }
00209 
00210 
00211 protected:
00212 
00217     virtual void cpRec(node v, PertinentGraph &Gp) const=0;
00218 
00220     edge cpAddEdge(edge eOrig, PertinentGraph &Gp) const
00221     {
00222         edge eP = Gp.m_P.newEdge(cpAddNode(eOrig->source(),Gp),cpAddNode(eOrig->target(),Gp));
00223         Gp.m_origE[eP] = eOrig;
00224         return eP;
00225     }
00226 
00228     node cpAddNode(node vOrig, PertinentGraph &Gp) const
00229     {
00230         node &vP = (*m_cpV)[vOrig];
00231         if (vP == 0) {
00232             m_cpVAdded.pushBack(vOrig);
00233             Gp.m_origV[vP = Gp.m_P.newNode()] = vOrig;
00234         }
00235         return vP;
00236     }
00237 
00238 
00239     // auxiliary members used for computing pertinent graphs
00240     mutable NodeArray<node> *m_cpV;       
00241     mutable SList<node>      m_cpVAdded;  
00242 
00243 }; // class SPQRTree
00244 
00245 
00246 } // end namespace ogdf
00247 
00248 
00249 #endif