1 /** \file 2 * \brief Declaration of class StaticSPQRTree 3 * 4 * \author Carsten Gutwenger 5 * 6 * \par License: 7 * This file is part of the Open Graph Drawing Framework (OGDF). 8 * 9 * \par 10 * Copyright (C)<br> 11 * See README.md in the OGDF root directory for details. 12 * 13 * \par 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License 16 * Version 2 or 3 as published by the Free Software Foundation; 17 * see the file LICENSE.txt included in the packaging of this file 18 * for details. 19 * 20 * \par 21 * This program is distributed in the hope that it will be useful, 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * GNU General Public License for more details. 25 * 26 * \par 27 * You should have received a copy of the GNU General Public 28 * License along with this program; if not, see 29 * http://www.gnu.org/copyleft/gpl.html 30 */ 31 32 #pragma once 33 34 #include <ogdf/decomposition/SPQRTree.h> 35 #include <ogdf/decomposition/StaticSkeleton.h> 36 #include <ogdf/graphalg/Triconnectivity.h> 37 38 namespace ogdf { 39 40 /** 41 * \brief Linear-time implementation of static SPQR-trees. 42 * 43 * @ingroup decomp 44 * 45 * The class StaticSPQRTree maintains the arrangement of the triconnected 46 * components of a biconnected multi-graph \a G [Hopcroft, Tarjan 1973] 47 * as a so-called SPQR tree \a T [Fi Battista, Tamassia, 1996]. We 48 * call \a G the original graph of \a T. 49 * The class StaticSPQRTree supports only the statical construction 50 * of an SPQR-tree for a given graph \a G, dynamic updates are 51 * not supported. 52 * 53 * Each node of the tree has an associated type (represented by 54 * SPQRTree::NodeType), which is either SNode, PNode, or 55 * RNode, and a skeleton (represented by the class StaticSkeleton). 56 * The skeletons of the nodes of \a T are in one-to-one 57 * correspondence to the triconnected components of \a G, i.e., 58 * S-nodes correspond to polygons, P-nodes to bonds, and 59 * R-nodes to triconnected graphs. 60 * 61 * In our representation of SPQR-trees, Q-nodes are omitted. Instead, 62 * the skeleton S of a node \a v in \a T contains two types of edges: 63 * real edges, which correspond to edges in \a G, and virtual edges, which 64 * correspond to edges in \a T having \a v as an endpoint. 65 * There is a special edge \a er in G at which \a T is rooted, i.e., the 66 * root node of \a T is the node whose skeleton contains the real edge 67 * corresponding to \a er. 68 * 69 * The reference edge of the skeleton of the root node is \a er, the 70 * reference edge of the skeleton \a S of a non-root node \a v is the virtual 71 * edge in \a S that corresponds to the tree edge (parent(\a v),\a v). 72 */ 73 class OGDF_EXPORT StaticSPQRTree : public virtual SPQRTree 74 { 75 public: 76 friend class StaticSkeleton; 77 78 // constructors 79 80 /** 81 * \brief Creates an SPQR tree \a T for graph \p G rooted at the first edge of \p G. 82 * \pre \p G is biconnected and contains at least 3 nodes, 83 * or \p G has exactly 2 nodes and at least 3 edges. 84 */ StaticSPQRTree(const Graph & G)85 explicit StaticSPQRTree(const Graph &G) : m_skOf(G), m_copyOf(G) { OGDF_ASSERT(G.numberOfEdges() > 0); m_pGraph = &G; init(G.firstEdge()); } 86 87 /** 88 * \brief Creates an SPQR tree \a T for graph \p G rooted at the edge \p e. 89 * \pre \p e is in \p G, \p G is biconnected and contains at least 3 nodes, 90 * or \p G has exactly 2 nodes and at least 3 edges. 91 */ StaticSPQRTree(const Graph & G,edge e)92 StaticSPQRTree(const Graph &G, edge e) : m_skOf(G), m_copyOf(G) { m_pGraph = &G; init(e); } 93 94 /** 95 * \brief Creates an SPQR tree \a T for graph \p G rooted at the first edge of \p G. 96 * \pre \p G is biconnected and contains at least 3 nodes, 97 * or \p G has exactly 2 nodes and at least 3 edges. 98 */ StaticSPQRTree(const Graph & G,Triconnectivity & tricComp)99 StaticSPQRTree(const Graph &G, Triconnectivity &tricComp) : m_skOf(G), m_copyOf(G) { m_pGraph = &G; init(G.firstEdge(),tricComp); } 100 101 //! Destructor. 102 ~StaticSPQRTree(); 103 104 //! \name Access operations 105 //! @{ 106 107 //! Returns a reference to the original graph \a G. originalGraph()108 const Graph &originalGraph() const override { return *m_pGraph; } 109 110 //! Returns a reference to the tree \a T. tree()111 const Graph &tree() const override { return m_tree; } 112 113 //! Returns the edge of \a G at which \a T is rooted. rootEdge()114 edge rootEdge() const override { return m_rootEdge; } 115 116 //! Returns the root node of \a T. rootNode()117 node rootNode() const override { return m_rootNode; } 118 119 //! Returns the number of S-nodes in \a T. numberOfSNodes()120 int numberOfSNodes() const override { return m_numS; } 121 122 //! Returns the number of P-nodes in \a T. numberOfPNodes()123 int numberOfPNodes() const override { return m_numP; } 124 125 //! Returns the number of R-nodes in \a T. numberOfRNodes()126 int numberOfRNodes() const override { return m_numR; } 127 128 /** 129 * \brief Returns the type of node \p v. 130 * \pre \p v is a node in \a T 131 */ typeOf(node v)132 NodeType typeOf(node v) const override { return m_type[v]; } 133 134 //! Returns the list of all nodes with type \p t. 135 List<node> nodesOfType(NodeType t) const override; 136 137 /** 138 * \brief Returns the skeleton of node \p v. 139 * \pre \p v is a node in \a T 140 */ skeleton(node v)141 Skeleton &skeleton(node v) const override { return *m_sk[v]; } 142 143 /** 144 * \brief Returns the edge in skeleton of source(\p e) that corresponds to tree edge \p e. 145 * \pre \p e is an edge in \a T 146 */ skeletonEdgeSrc(edge e)147 edge skeletonEdgeSrc(edge e) const { return m_skEdgeSrc[e]; } 148 149 /** 150 * \brief Returns the edge in skeleton of target(\p e) that corresponds to tree edge \p e. 151 * \pre \p e is an edge in \a T 152 */ skeletonEdgeTgt(edge e)153 edge skeletonEdgeTgt(edge e) const { return m_skEdgeTgt[e]; } 154 155 /** 156 * \brief Returns the skeleton that contains the real edge \p e. 157 * \pre \p e is an edge in \a G 158 */ skeletonOfReal(edge e)159 const Skeleton &skeletonOfReal(edge e) const override { return *m_skOf[e]; } 160 161 /** 162 * \brief Returns the skeleton edge that corresponds to the real edge \p e. 163 * \pre \p e is an edge in \a G 164 */ copyOfReal(edge e)165 edge copyOfReal(edge e) const override { return m_copyOf[e]; } 166 167 //! @} 168 //! \name Update operations 169 //! @{ 170 171 /** 172 * \brief Roots \a T at edge \p e and returns the new root node of \a T. 173 * \pre \p e is an edge in \a G 174 */ 175 node rootTreeAt(edge e) override; 176 177 /** 178 * \brief Roots \a T at node \p v and returns \p v. 179 * \pre \p v is a node in \a T 180 */ 181 node rootTreeAt(node v) override; 182 183 //! @} 184 185 protected: 186 187 //! Initialization (called by constructor). 188 void init(edge e); 189 190 //! Initialization (called by constructor). 191 void init(edge eRef, Triconnectivity &tricComp); 192 193 //! Recursively performs rooting of tree. 194 void rootRec(node v, edge ef); 195 196 /** 197 * \brief Recursively performs the task of adding edges (and nodes) 198 * to the pertinent graph \p Gp for each involved skeleton graph. 199 */ cpRec(node v,PertinentGraph & Gp)200 void cpRec(node v, PertinentGraph &Gp) const override 201 { 202 const Skeleton &S = skeleton(v); 203 204 for(edge e : S.getGraph().edges) { 205 edge eOrig = S.realEdge(e); 206 if (eOrig != nullptr) cpAddEdge(eOrig,Gp); 207 } 208 209 for(adjEntry adj : v->adjEntries) { 210 node w = adj->theEdge()->target(); 211 if (w != v) cpRec(w,Gp); 212 } 213 } 214 215 216 const Graph *m_pGraph; //!< pointer to original graph 217 Graph m_tree; //!< underlying tree graph 218 219 edge m_rootEdge; //!< edge of \a G at which \a T is rooted 220 node m_rootNode; //!< root node of \a T 221 222 int m_numS; //!< number of S-nodes 223 int m_numP; //!< number of P-nodes 224 int m_numR; //!< number of R-nodes 225 226 NodeArray<NodeType> m_type; //!< type of nodes in \a T 227 228 NodeArray<StaticSkeleton *> m_sk; //!< pointer to skeleton of a node in \a T 229 EdgeArray<edge> m_skEdgeSrc; //!< corresponding edge in skeleton(source(\a e)) 230 EdgeArray<edge> m_skEdgeTgt; //!< corresponding edge in skeleton(target(\a e)) 231 232 EdgeArray<StaticSkeleton *> m_skOf; //!< skeleton containing real edge \a e 233 EdgeArray<edge> m_copyOf; //!< skeleton edge corresponding to real edge \a e 234 }; 235 236 } 237