| 
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-  | 
         | 
     2  *  | 
         | 
     3  * This file is a part of LEMON, a generic C++ optimization library.  | 
         | 
     4  *  | 
         | 
     5  * Copyright (C) 2003-2008  | 
         | 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport  | 
         | 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).  | 
         | 
     8  *  | 
         | 
     9  * Permission to use, modify and distribute this software is granted  | 
         | 
    10  * provided that this copyright notice appears in all copies. For  | 
         | 
    11  * precise terms see the accompanying LICENSE file.  | 
         | 
    12  *  | 
         | 
    13  * This software is provided "AS IS" with no warranty of any kind,  | 
         | 
    14  * express or implied, and with no claim as to its suitability for any  | 
         | 
    15  * purpose.  | 
         | 
    16  *  | 
         | 
    17  */  | 
         | 
    18   | 
         | 
    19 #ifndef LEMON_EDGE_SET_H  | 
         | 
    20 #define LEMON_EDGE_SET_H  | 
         | 
    21   | 
         | 
    22 #include <lemon/core.h>  | 
         | 
    23 #include <lemon/bits/edge_set_extender.h>  | 
         | 
    24   | 
         | 
    25 /// \ingroup semi_adaptors  | 
         | 
    26 /// \file  | 
         | 
    27 /// \brief ArcSet and EdgeSet classes.  | 
         | 
    28 ///  | 
         | 
    29 /// Graphs which use another graph's node-set as own.  | 
         | 
    30 namespace lemon { | 
         | 
    31   | 
         | 
    32   template <typename _Graph>  | 
         | 
    33   class ListArcSetBase { | 
         | 
    34   public:  | 
         | 
    35   | 
         | 
    36     typedef _Graph Graph;  | 
         | 
    37     typedef typename Graph::Node Node;  | 
         | 
    38     typedef typename Graph::NodeIt NodeIt;  | 
         | 
    39   | 
         | 
    40   protected:  | 
         | 
    41   | 
         | 
    42     struct NodeT { | 
         | 
    43       int first_out, first_in;  | 
         | 
    44       NodeT() : first_out(-1), first_in(-1) {} | 
         | 
    45     };  | 
         | 
    46   | 
         | 
    47     typedef typename ItemSetTraits<Graph, Node>::  | 
         | 
    48     template Map<NodeT>::Type NodesImplBase;  | 
         | 
    49   | 
         | 
    50     NodesImplBase* nodes;  | 
         | 
    51   | 
         | 
    52     struct ArcT { | 
         | 
    53       Node source, target;  | 
         | 
    54       int next_out, next_in;  | 
         | 
    55       int prev_out, prev_in;  | 
         | 
    56       ArcT() : prev_out(-1), prev_in(-1) {} | 
         | 
    57     };  | 
         | 
    58   | 
         | 
    59     std::vector<ArcT> arcs;  | 
         | 
    60   | 
         | 
    61     int first_arc;  | 
         | 
    62     int first_free_arc;  | 
         | 
    63   | 
         | 
    64     const Graph* graph;  | 
         | 
    65   | 
         | 
    66     void initalize(const Graph& _graph, NodesImplBase& _nodes) { | 
         | 
    67       graph = &_graph;  | 
         | 
    68       nodes = &_nodes;  | 
         | 
    69     }  | 
         | 
    70   | 
         | 
    71   public:  | 
         | 
    72   | 
         | 
    73     class Arc { | 
         | 
    74       friend class ListArcSetBase<Graph>;  | 
         | 
    75     protected:  | 
         | 
    76       Arc(int _id) : id(_id) {} | 
         | 
    77       int id;  | 
         | 
    78     public:  | 
         | 
    79       Arc() {} | 
         | 
    80       Arc(Invalid) : id(-1) {} | 
         | 
    81       bool operator==(const Arc& arc) const { return id == arc.id; } | 
         | 
    82       bool operator!=(const Arc& arc) const { return id != arc.id; } | 
         | 
    83       bool operator<(const Arc& arc) const { return id < arc.id; } | 
         | 
    84     };  | 
         | 
    85   | 
         | 
    86     ListArcSetBase() : first_arc(-1), first_free_arc(-1) {} | 
         | 
    87   | 
         | 
    88     Arc addArc(const Node& u, const Node& v) { | 
         | 
    89       int n;  | 
         | 
    90       if (first_free_arc == -1) { | 
         | 
    91         n = arcs.size();  | 
         | 
    92         arcs.push_back(ArcT());  | 
         | 
    93       } else { | 
         | 
    94         n = first_free_arc;  | 
         | 
    95         first_free_arc = arcs[first_free_arc].next_in;  | 
         | 
    96       }  | 
         | 
    97       arcs[n].next_in = (*nodes)[v].first_in;  | 
         | 
    98       if ((*nodes)[v].first_in != -1) { | 
         | 
    99         arcs[(*nodes)[v].first_in].prev_in = n;  | 
         | 
   100       }  | 
         | 
   101       (*nodes)[v].first_in = n;  | 
         | 
   102       arcs[n].next_out = (*nodes)[u].first_out;  | 
         | 
   103       if ((*nodes)[u].first_out != -1) { | 
         | 
   104         arcs[(*nodes)[u].first_out].prev_out = n;  | 
         | 
   105       }  | 
         | 
   106       (*nodes)[u].first_out = n;  | 
         | 
   107       arcs[n].source = u;  | 
         | 
   108       arcs[n].target = v;  | 
         | 
   109       return Arc(n);  | 
         | 
   110     }  | 
         | 
   111   | 
         | 
   112     void erase(const Arc& arc) { | 
         | 
   113       int n = arc.id;  | 
         | 
   114       if (arcs[n].prev_in != -1) { | 
         | 
   115         arcs[arcs[n].prev_in].next_in = arcs[n].next_in;  | 
         | 
   116       } else { | 
         | 
   117         (*nodes)[arcs[n].target].first_in = arcs[n].next_in;  | 
         | 
   118       }  | 
         | 
   119       if (arcs[n].next_in != -1) { | 
         | 
   120         arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;  | 
         | 
   121       }  | 
         | 
   122   | 
         | 
   123       if (arcs[n].prev_out != -1) { | 
         | 
   124         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;  | 
         | 
   125       } else { | 
         | 
   126         (*nodes)[arcs[n].source].first_out = arcs[n].next_out;  | 
         | 
   127       }  | 
         | 
   128       if (arcs[n].next_out != -1) { | 
         | 
   129         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;  | 
         | 
   130       }  | 
         | 
   131   | 
         | 
   132     }  | 
         | 
   133   | 
         | 
   134     void clear() { | 
         | 
   135       Node node;  | 
         | 
   136       for (first(node); node != INVALID; next(node)) { | 
         | 
   137         (*nodes)[node].first_in = -1;  | 
         | 
   138         (*nodes)[node].first_out = -1;  | 
         | 
   139       }  | 
         | 
   140       arcs.clear();  | 
         | 
   141       first_arc = -1;  | 
         | 
   142       first_free_arc = -1;  | 
         | 
   143     }  | 
         | 
   144   | 
         | 
   145     void first(Node& node) const { | 
         | 
   146       graph->first(node);  | 
         | 
   147     }  | 
         | 
   148   | 
         | 
   149     void next(Node& node) const { | 
         | 
   150       graph->next(node);  | 
         | 
   151     }  | 
         | 
   152   | 
         | 
   153     void first(Arc& arc) const { | 
         | 
   154       Node node;  | 
         | 
   155       first(node);  | 
         | 
   156       while (node != INVALID && (*nodes)[node].first_in == -1) { | 
         | 
   157         next(node);  | 
         | 
   158       }  | 
         | 
   159       arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;  | 
         | 
   160     }  | 
         | 
   161   | 
         | 
   162     void next(Arc& arc) const { | 
         | 
   163       if (arcs[arc.id].next_in != -1) { | 
         | 
   164         arc.id = arcs[arc.id].next_in;  | 
         | 
   165       } else { | 
         | 
   166         Node node = arcs[arc.id].target;  | 
         | 
   167         next(node);  | 
         | 
   168         while (node != INVALID && (*nodes)[node].first_in == -1) { | 
         | 
   169           next(node);  | 
         | 
   170         }  | 
         | 
   171         arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;  | 
         | 
   172       }  | 
         | 
   173     }  | 
         | 
   174   | 
         | 
   175     void firstOut(Arc& arc, const Node& node) const { | 
         | 
   176       arc.id = (*nodes)[node].first_out;  | 
         | 
   177     }  | 
         | 
   178   | 
         | 
   179     void nextOut(Arc& arc) const { | 
         | 
   180       arc.id = arcs[arc.id].next_out;  | 
         | 
   181     }  | 
         | 
   182   | 
         | 
   183     void firstIn(Arc& arc, const Node& node) const { | 
         | 
   184       arc.id = (*nodes)[node].first_in;  | 
         | 
   185     }  | 
         | 
   186   | 
         | 
   187     void nextIn(Arc& arc) const { | 
         | 
   188       arc.id = arcs[arc.id].next_in;  | 
         | 
   189     }  | 
         | 
   190   | 
         | 
   191     int id(const Node& node) const { return graph->id(node); } | 
         | 
   192     int id(const Arc& arc) const { return arc.id; } | 
         | 
   193   | 
         | 
   194     Node nodeFromId(int ix) const { return graph->nodeFromId(ix); } | 
         | 
   195     Arc arcFromId(int ix) const { return Arc(ix); } | 
         | 
   196   | 
         | 
   197     int maxNodeId() const { return graph->maxNodeId(); }; | 
         | 
   198     int maxArcId() const { return arcs.size() - 1; } | 
         | 
   199   | 
         | 
   200     Node source(const Arc& arc) const { return arcs[arc.id].source;} | 
         | 
   201     Node target(const Arc& arc) const { return arcs[arc.id].target;} | 
         | 
   202   | 
         | 
   203     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;  | 
         | 
   204   | 
         | 
   205     NodeNotifier& notifier(Node) const { | 
         | 
   206       return graph->notifier(Node());  | 
         | 
   207     }  | 
         | 
   208   | 
         | 
   209     template <typename _Value>  | 
         | 
   210     class NodeMap : public Graph::template NodeMap<_Value> { | 
         | 
   211     public:  | 
         | 
   212   | 
         | 
   213       typedef typename _Graph::template NodeMap<_Value> Parent;  | 
         | 
   214   | 
         | 
   215       explicit NodeMap(const ListArcSetBase<Graph>& arcset)  | 
         | 
   216         : Parent(*arcset.graph) {} | 
         | 
   217   | 
         | 
   218       NodeMap(const ListArcSetBase<Graph>& arcset, const _Value& value)  | 
         | 
   219         : Parent(*arcset.graph, value) {} | 
         | 
   220   | 
         | 
   221       NodeMap& operator=(const NodeMap& cmap) { | 
         | 
   222         return operator=<NodeMap>(cmap);  | 
         | 
   223       }  | 
         | 
   224   | 
         | 
   225       template <typename CMap>  | 
         | 
   226       NodeMap& operator=(const CMap& cmap) { | 
         | 
   227         Parent::operator=(cmap);  | 
         | 
   228         return *this;  | 
         | 
   229       }  | 
         | 
   230     };  | 
         | 
   231   | 
         | 
   232   };  | 
         | 
   233   | 
         | 
   234   /// \ingroup semi_adaptors  | 
         | 
   235   ///  | 
         | 
   236   /// \brief Digraph using a node set of another digraph or graph and  | 
         | 
   237   /// an own arc set.  | 
         | 
   238   ///  | 
         | 
   239   /// This structure can be used to establish another directed graph  | 
         | 
   240   /// over a node set of an existing one. This class uses the same  | 
         | 
   241   /// Node type as the underlying graph, and each valid node of the  | 
         | 
   242   /// original graph is valid in this arc set, therefore the node  | 
         | 
   243   /// objects of the original graph can be used directly with this  | 
         | 
   244   /// class. The node handling functions (id handling, observing, and  | 
         | 
   245   /// iterators) works equivalently as in the original graph.  | 
         | 
   246   ///  | 
         | 
   247   /// This implementation is based on doubly-linked lists, from each  | 
         | 
   248   /// node the outgoing and the incoming arcs make up lists, therefore  | 
         | 
   249   /// one arc can be erased in constant time. It also makes possible,  | 
         | 
   250   /// that node can be removed from the underlying graph, in this case  | 
         | 
   251   /// all arcs incident to the given node is erased from the arc set.  | 
         | 
   252   ///  | 
         | 
   253   /// \param _Graph The type of the graph which shares its node set with  | 
         | 
   254   /// this class. Its interface must conform to the  | 
         | 
   255   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"  | 
         | 
   256   /// concept.  | 
         | 
   257   ///  | 
         | 
   258   /// This class is fully conform to the \ref concepts::Digraph  | 
         | 
   259   /// "Digraph" concept.  | 
         | 
   260   template <typename _Graph>  | 
         | 
   261   class ListArcSet : public ArcSetExtender<ListArcSetBase<_Graph> > { | 
         | 
   262   | 
         | 
   263   public:  | 
         | 
   264   | 
         | 
   265     typedef ArcSetExtender<ListArcSetBase<_Graph> > Parent;  | 
         | 
   266   | 
         | 
   267     typedef typename Parent::Node Node;  | 
         | 
   268     typedef typename Parent::Arc Arc;  | 
         | 
   269   | 
         | 
   270     typedef _Graph Graph;  | 
         | 
   271   | 
         | 
   272   | 
         | 
   273     typedef typename Parent::NodesImplBase NodesImplBase;  | 
         | 
   274   | 
         | 
   275     void eraseNode(const Node& node) { | 
         | 
   276       Arc arc;  | 
         | 
   277       Parent::firstOut(arc, node);  | 
         | 
   278       while (arc != INVALID ) { | 
         | 
   279         erase(arc);  | 
         | 
   280         Parent::firstOut(arc, node);  | 
         | 
   281       }  | 
         | 
   282   | 
         | 
   283       Parent::firstIn(arc, node);  | 
         | 
   284       while (arc != INVALID ) { | 
         | 
   285         erase(arc);  | 
         | 
   286         Parent::firstIn(arc, node);  | 
         | 
   287       }  | 
         | 
   288     }  | 
         | 
   289   | 
         | 
   290     void clearNodes() { | 
         | 
   291       Parent::clear();  | 
         | 
   292     }  | 
         | 
   293   | 
         | 
   294     class NodesImpl : public NodesImplBase { | 
         | 
   295     public:  | 
         | 
   296       typedef NodesImplBase Parent;  | 
         | 
   297   | 
         | 
   298       NodesImpl(const Graph& graph, ListArcSet& arcset)  | 
         | 
   299         : Parent(graph), _arcset(arcset) {} | 
         | 
   300   | 
         | 
   301       virtual ~NodesImpl() {} | 
         | 
   302   | 
         | 
   303     protected:  | 
         | 
   304   | 
         | 
   305       virtual void erase(const Node& node) { | 
         | 
   306         _arcset.eraseNode(node);  | 
         | 
   307         Parent::erase(node);  | 
         | 
   308       }  | 
         | 
   309       virtual void erase(const std::vector<Node>& nodes) { | 
         | 
   310         for (int i = 0; i < int(nodes.size()); ++i) { | 
         | 
   311           _arcset.eraseNode(nodes[i]);  | 
         | 
   312         }  | 
         | 
   313         Parent::erase(nodes);  | 
         | 
   314       }  | 
         | 
   315       virtual void clear() { | 
         | 
   316         _arcset.clearNodes();  | 
         | 
   317         Parent::clear();  | 
         | 
   318       }  | 
         | 
   319   | 
         | 
   320     private:  | 
         | 
   321       ListArcSet& _arcset;  | 
         | 
   322     };  | 
         | 
   323   | 
         | 
   324     NodesImpl nodes;  | 
         | 
   325   | 
         | 
   326   public:  | 
         | 
   327   | 
         | 
   328     /// \brief Constructor of the ArcSet.  | 
         | 
   329     ///  | 
         | 
   330     /// Constructor of the ArcSet.  | 
         | 
   331     ListArcSet(const Graph& graph) : nodes(graph, *this) { | 
         | 
   332       Parent::initalize(graph, nodes);  | 
         | 
   333     }  | 
         | 
   334   | 
         | 
   335     /// \brief Add a new arc to the digraph.  | 
         | 
   336     ///  | 
         | 
   337     /// Add a new arc to the digraph with source node \c s  | 
         | 
   338     /// and target node \c t.  | 
         | 
   339     /// \return the new arc.  | 
         | 
   340     Arc addArc(const Node& s, const Node& t) { | 
         | 
   341       return Parent::addArc(s, t);  | 
         | 
   342     }  | 
         | 
   343   | 
         | 
   344     /// \brief Erase an arc from the digraph.  | 
         | 
   345     ///  | 
         | 
   346     /// Erase an arc \c a from the digraph.  | 
         | 
   347     void erase(const Arc& a) { | 
         | 
   348       return Parent::erase(a);  | 
         | 
   349     }  | 
         | 
   350   | 
         | 
   351   };  | 
         | 
   352   | 
         | 
   353   template <typename _Graph>  | 
         | 
   354   class ListEdgeSetBase { | 
         | 
   355   public:  | 
         | 
   356   | 
         | 
   357     typedef _Graph Graph;  | 
         | 
   358     typedef typename Graph::Node Node;  | 
         | 
   359     typedef typename Graph::NodeIt NodeIt;  | 
         | 
   360   | 
         | 
   361   protected:  | 
         | 
   362   | 
         | 
   363     struct NodeT { | 
         | 
   364       int first_out;  | 
         | 
   365       NodeT() : first_out(-1) {} | 
         | 
   366     };  | 
         | 
   367   | 
         | 
   368     typedef typename ItemSetTraits<Graph, Node>::  | 
         | 
   369     template Map<NodeT>::Type NodesImplBase;  | 
         | 
   370   | 
         | 
   371     NodesImplBase* nodes;  | 
         | 
   372   | 
         | 
   373     struct ArcT { | 
         | 
   374       Node target;  | 
         | 
   375       int prev_out, next_out;  | 
         | 
   376       ArcT() : prev_out(-1), next_out(-1) {} | 
         | 
   377     };  | 
         | 
   378   | 
         | 
   379     std::vector<ArcT> arcs;  | 
         | 
   380   | 
         | 
   381     int first_arc;  | 
         | 
   382     int first_free_arc;  | 
         | 
   383   | 
         | 
   384     const Graph* graph;  | 
         | 
   385   | 
         | 
   386     void initalize(const Graph& _graph, NodesImplBase& _nodes) { | 
         | 
   387       graph = &_graph;  | 
         | 
   388       nodes = &_nodes;  | 
         | 
   389     }  | 
         | 
   390   | 
         | 
   391   public:  | 
         | 
   392   | 
         | 
   393     class Edge { | 
         | 
   394       friend class ListEdgeSetBase;  | 
         | 
   395     protected:  | 
         | 
   396   | 
         | 
   397       int id;  | 
         | 
   398       explicit Edge(int _id) { id = _id;} | 
         | 
   399   | 
         | 
   400     public:  | 
         | 
   401       Edge() {} | 
         | 
   402       Edge (Invalid) { id = -1; } | 
         | 
   403       bool operator==(const Edge& arc) const {return id == arc.id;} | 
         | 
   404       bool operator!=(const Edge& arc) const {return id != arc.id;} | 
         | 
   405       bool operator<(const Edge& arc) const {return id < arc.id;} | 
         | 
   406     };  | 
         | 
   407   | 
         | 
   408     class Arc { | 
         | 
   409       friend class ListEdgeSetBase;  | 
         | 
   410     protected:  | 
         | 
   411       Arc(int _id) : id(_id) {} | 
         | 
   412       int id;  | 
         | 
   413     public:  | 
         | 
   414       operator Edge() const { return edgeFromId(id / 2); } | 
         | 
   415   | 
         | 
   416       Arc() {} | 
         | 
   417       Arc(Invalid) : id(-1) {} | 
         | 
   418       bool operator==(const Arc& arc) const { return id == arc.id; } | 
         | 
   419       bool operator!=(const Arc& arc) const { return id != arc.id; } | 
         | 
   420       bool operator<(const Arc& arc) const { return id < arc.id; } | 
         | 
   421     };  | 
         | 
   422   | 
         | 
   423     ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {} | 
         | 
   424   | 
         | 
   425     Edge addEdge(const Node& u, const Node& v) { | 
         | 
   426       int n;  | 
         | 
   427   | 
         | 
   428       if (first_free_arc == -1) { | 
         | 
   429         n = arcs.size();  | 
         | 
   430         arcs.push_back(ArcT());  | 
         | 
   431         arcs.push_back(ArcT());  | 
         | 
   432       } else { | 
         | 
   433         n = first_free_arc;  | 
         | 
   434         first_free_arc = arcs[n].next_out;  | 
         | 
   435       }  | 
         | 
   436   | 
         | 
   437       arcs[n].target = u;  | 
         | 
   438       arcs[n | 1].target = v;  | 
         | 
   439   | 
         | 
   440       arcs[n].next_out = (*nodes)[v].first_out;  | 
         | 
   441       if ((*nodes)[v].first_out != -1) { | 
         | 
   442         arcs[(*nodes)[v].first_out].prev_out = n;  | 
         | 
   443       }  | 
         | 
   444       (*nodes)[v].first_out = n;  | 
         | 
   445       arcs[n].prev_out = -1;  | 
         | 
   446   | 
         | 
   447       if ((*nodes)[u].first_out != -1) { | 
         | 
   448         arcs[(*nodes)[u].first_out].prev_out = (n | 1);  | 
         | 
   449       }  | 
         | 
   450       arcs[n | 1].next_out = (*nodes)[u].first_out;  | 
         | 
   451       (*nodes)[u].first_out = (n | 1);  | 
         | 
   452       arcs[n | 1].prev_out = -1;  | 
         | 
   453   | 
         | 
   454       return Edge(n / 2);  | 
         | 
   455     }  | 
         | 
   456   | 
         | 
   457     void erase(const Edge& arc) { | 
         | 
   458       int n = arc.id * 2;  | 
         | 
   459   | 
         | 
   460       if (arcs[n].next_out != -1) { | 
         | 
   461         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;  | 
         | 
   462       }  | 
         | 
   463   | 
         | 
   464       if (arcs[n].prev_out != -1) { | 
         | 
   465         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;  | 
         | 
   466       } else { | 
         | 
   467         (*nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;  | 
         | 
   468       }  | 
         | 
   469   | 
         | 
   470       if (arcs[n | 1].next_out != -1) { | 
         | 
   471         arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;  | 
         | 
   472       }  | 
         | 
   473   | 
         | 
   474       if (arcs[n | 1].prev_out != -1) { | 
         | 
   475         arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;  | 
         | 
   476       } else { | 
         | 
   477         (*nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;  | 
         | 
   478       }  | 
         | 
   479   | 
         | 
   480       arcs[n].next_out = first_free_arc;  | 
         | 
   481       first_free_arc = n;  | 
         | 
   482   | 
         | 
   483     }  | 
         | 
   484   | 
         | 
   485     void clear() { | 
         | 
   486       Node node;  | 
         | 
   487       for (first(node); node != INVALID; next(node)) { | 
         | 
   488         (*nodes)[node].first_out = -1;  | 
         | 
   489       }  | 
         | 
   490       arcs.clear();  | 
         | 
   491       first_arc = -1;  | 
         | 
   492       first_free_arc = -1;  | 
         | 
   493     }  | 
         | 
   494   | 
         | 
   495     void first(Node& node) const { | 
         | 
   496       graph->first(node);  | 
         | 
   497     }  | 
         | 
   498   | 
         | 
   499     void next(Node& node) const { | 
         | 
   500       graph->next(node);  | 
         | 
   501     }  | 
         | 
   502   | 
         | 
   503     void first(Arc& arc) const { | 
         | 
   504       Node node;  | 
         | 
   505       first(node);  | 
         | 
   506       while (node != INVALID && (*nodes)[node].first_out == -1) { | 
         | 
   507         next(node);  | 
         | 
   508       }  | 
         | 
   509       arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;  | 
         | 
   510     }  | 
         | 
   511   | 
         | 
   512     void next(Arc& arc) const { | 
         | 
   513       if (arcs[arc.id].next_out != -1) { | 
         | 
   514         arc.id = arcs[arc.id].next_out;  | 
         | 
   515       } else { | 
         | 
   516         Node node = arcs[arc.id ^ 1].target;  | 
         | 
   517         next(node);  | 
         | 
   518         while(node != INVALID && (*nodes)[node].first_out == -1) { | 
         | 
   519           next(node);  | 
         | 
   520         }  | 
         | 
   521         arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;  | 
         | 
   522       }  | 
         | 
   523     }  | 
         | 
   524   | 
         | 
   525     void first(Edge& edge) const { | 
         | 
   526       Node node;  | 
         | 
   527       first(node);  | 
         | 
   528       while (node != INVALID) { | 
         | 
   529         edge.id = (*nodes)[node].first_out;  | 
         | 
   530         while ((edge.id & 1) != 1) { | 
         | 
   531           edge.id = arcs[edge.id].next_out;  | 
         | 
   532         }  | 
         | 
   533         if (edge.id != -1) { | 
         | 
   534           edge.id /= 2;  | 
         | 
   535           return;  | 
         | 
   536         }  | 
         | 
   537         next(node);  | 
         | 
   538       }  | 
         | 
   539       edge.id = -1;  | 
         | 
   540     }  | 
         | 
   541   | 
         | 
   542     void next(Edge& edge) const { | 
         | 
   543       Node node = arcs[edge.id * 2].target;  | 
         | 
   544       edge.id = arcs[(edge.id * 2) | 1].next_out;  | 
         | 
   545       while ((edge.id & 1) != 1) { | 
         | 
   546         edge.id = arcs[edge.id].next_out;  | 
         | 
   547       }  | 
         | 
   548       if (edge.id != -1) { | 
         | 
   549         edge.id /= 2;  | 
         | 
   550         return;  | 
         | 
   551       }  | 
         | 
   552       next(node);  | 
         | 
   553       while (node != INVALID) { | 
         | 
   554         edge.id = (*nodes)[node].first_out;  | 
         | 
   555         while ((edge.id & 1) != 1) { | 
         | 
   556           edge.id = arcs[edge.id].next_out;  | 
         | 
   557         }  | 
         | 
   558         if (edge.id != -1) { | 
         | 
   559           edge.id /= 2;  | 
         | 
   560           return;  | 
         | 
   561         }  | 
         | 
   562         next(node);  | 
         | 
   563       }  | 
         | 
   564       edge.id = -1;  | 
         | 
   565     }  | 
         | 
   566   | 
         | 
   567     void firstOut(Arc& arc, const Node& node) const { | 
         | 
   568       arc.id = (*nodes)[node].first_out;  | 
         | 
   569     }  | 
         | 
   570   | 
         | 
   571     void nextOut(Arc& arc) const { | 
         | 
   572       arc.id = arcs[arc.id].next_out;  | 
         | 
   573     }  | 
         | 
   574   | 
         | 
   575     void firstIn(Arc& arc, const Node& node) const { | 
         | 
   576       arc.id = (((*nodes)[node].first_out) ^ 1);  | 
         | 
   577       if (arc.id == -2) arc.id = -1;  | 
         | 
   578     }  | 
         | 
   579   | 
         | 
   580     void nextIn(Arc& arc) const { | 
         | 
   581       arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);  | 
         | 
   582       if (arc.id == -2) arc.id = -1;  | 
         | 
   583     }  | 
         | 
   584   | 
         | 
   585     void firstInc(Edge &arc, bool& dir, const Node& node) const { | 
         | 
   586       int de = (*nodes)[node].first_out;  | 
         | 
   587       if (de != -1 ) { | 
         | 
   588         arc.id = de / 2;  | 
         | 
   589         dir = ((de & 1) == 1);  | 
         | 
   590       } else { | 
         | 
   591         arc.id = -1;  | 
         | 
   592         dir = true;  | 
         | 
   593       }  | 
         | 
   594     }  | 
         | 
   595     void nextInc(Edge &arc, bool& dir) const { | 
         | 
   596       int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);  | 
         | 
   597       if (de != -1 ) { | 
         | 
   598         arc.id = de / 2;  | 
         | 
   599         dir = ((de & 1) == 1);  | 
         | 
   600       } else { | 
         | 
   601         arc.id = -1;  | 
         | 
   602         dir = true;  | 
         | 
   603       }  | 
         | 
   604     }  | 
         | 
   605   | 
         | 
   606     static bool direction(Arc arc) { | 
         | 
   607       return (arc.id & 1) == 1;  | 
         | 
   608     }  | 
         | 
   609   | 
         | 
   610     static Arc direct(Edge edge, bool dir) { | 
         | 
   611       return Arc(edge.id * 2 + (dir ? 1 : 0));  | 
         | 
   612     }  | 
         | 
   613   | 
         | 
   614     int id(const Node& node) const { return graph->id(node); } | 
         | 
   615     static int id(Arc e) { return e.id; } | 
         | 
   616     static int id(Edge e) { return e.id; } | 
         | 
   617   | 
         | 
   618     Node nodeFromId(int id) const { return graph->nodeFromId(id); } | 
         | 
   619     static Arc arcFromId(int id) { return Arc(id);} | 
         | 
   620     static Edge edgeFromId(int id) { return Edge(id);} | 
         | 
   621   | 
         | 
   622     int maxNodeId() const { return graph->maxNodeId(); }; | 
         | 
   623     int maxEdgeId() const { return arcs.size() / 2 - 1; } | 
         | 
   624     int maxArcId() const { return arcs.size()-1; } | 
         | 
   625   | 
         | 
   626     Node source(Arc e) const { return arcs[e.id ^ 1].target; } | 
         | 
   627     Node target(Arc e) const { return arcs[e.id].target; } | 
         | 
   628   | 
         | 
   629     Node u(Edge e) const { return arcs[2 * e.id].target; } | 
         | 
   630     Node v(Edge e) const { return arcs[2 * e.id + 1].target; } | 
         | 
   631   | 
         | 
   632     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;  | 
         | 
   633   | 
         | 
   634     NodeNotifier& notifier(Node) const { | 
         | 
   635       return graph->notifier(Node());  | 
         | 
   636     }  | 
         | 
   637   | 
         | 
   638     template <typename _Value>  | 
         | 
   639     class NodeMap : public Graph::template NodeMap<_Value> { | 
         | 
   640     public:  | 
         | 
   641   | 
         | 
   642       typedef typename _Graph::template NodeMap<_Value> Parent;  | 
         | 
   643   | 
         | 
   644       explicit NodeMap(const ListEdgeSetBase<Graph>& arcset)  | 
         | 
   645         : Parent(*arcset.graph) {} | 
         | 
   646   | 
         | 
   647       NodeMap(const ListEdgeSetBase<Graph>& arcset, const _Value& value)  | 
         | 
   648         : Parent(*arcset.graph, value) {} | 
         | 
   649   | 
         | 
   650       NodeMap& operator=(const NodeMap& cmap) { | 
         | 
   651         return operator=<NodeMap>(cmap);  | 
         | 
   652       }  | 
         | 
   653   | 
         | 
   654       template <typename CMap>  | 
         | 
   655       NodeMap& operator=(const CMap& cmap) { | 
         | 
   656         Parent::operator=(cmap);  | 
         | 
   657         return *this;  | 
         | 
   658       }  | 
         | 
   659     };  | 
         | 
   660   | 
         | 
   661   };  | 
         | 
   662   | 
         | 
   663   /// \ingroup semi_adaptors  | 
         | 
   664   ///  | 
         | 
   665   /// \brief Graph using a node set of another digraph or graph and an  | 
         | 
   666   /// own edge set.  | 
         | 
   667   ///  | 
         | 
   668   /// This structure can be used to establish another graph over a  | 
         | 
   669   /// node set of an existing one. This class uses the same Node type  | 
         | 
   670   /// as the underlying graph, and each valid node of the original  | 
         | 
   671   /// graph is valid in this arc set, therefore the node objects of  | 
         | 
   672   /// the original graph can be used directly with this class. The  | 
         | 
   673   /// node handling functions (id handling, observing, and iterators)  | 
         | 
   674   /// works equivalently as in the original graph.  | 
         | 
   675   ///  | 
         | 
   676   /// This implementation is based on doubly-linked lists, from each  | 
         | 
   677   /// node the incident edges make up lists, therefore one edge can be  | 
         | 
   678   /// erased in constant time. It also makes possible, that node can  | 
         | 
   679   /// be removed from the underlying graph, in this case all edges  | 
         | 
   680   /// incident to the given node is erased from the arc set.  | 
         | 
   681   ///  | 
         | 
   682   /// \param _Graph The type of the graph which shares its node set  | 
         | 
   683   /// with this class. Its interface must conform to the  | 
         | 
   684   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"  | 
         | 
   685   /// concept.  | 
         | 
   686   ///  | 
         | 
   687   /// This class is fully conform to the \ref concepts::Graph "Graph"  | 
         | 
   688   /// concept.  | 
         | 
   689   template <typename _Graph>  | 
         | 
   690   class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > { | 
         | 
   691   | 
         | 
   692   public:  | 
         | 
   693   | 
         | 
   694     typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;  | 
         | 
   695   | 
         | 
   696     typedef typename Parent::Node Node;  | 
         | 
   697     typedef typename Parent::Arc Arc;  | 
         | 
   698     typedef typename Parent::Edge Edge;  | 
         | 
   699   | 
         | 
   700     typedef _Graph Graph;  | 
         | 
   701   | 
         | 
   702   | 
         | 
   703     typedef typename Parent::NodesImplBase NodesImplBase;  | 
         | 
   704   | 
         | 
   705     void eraseNode(const Node& node) { | 
         | 
   706       Arc arc;  | 
         | 
   707       Parent::firstOut(arc, node);  | 
         | 
   708       while (arc != INVALID ) { | 
         | 
   709         erase(arc);  | 
         | 
   710         Parent::firstOut(arc, node);  | 
         | 
   711       }  | 
         | 
   712   | 
         | 
   713     }  | 
         | 
   714   | 
         | 
   715     void clearNodes() { | 
         | 
   716       Parent::clear();  | 
         | 
   717     }  | 
         | 
   718   | 
         | 
   719     class NodesImpl : public NodesImplBase { | 
         | 
   720     public:  | 
         | 
   721       typedef NodesImplBase Parent;  | 
         | 
   722   | 
         | 
   723       NodesImpl(const Graph& graph, ListEdgeSet& arcset)  | 
         | 
   724         : Parent(graph), _arcset(arcset) {} | 
         | 
   725   | 
         | 
   726       virtual ~NodesImpl() {} | 
         | 
   727   | 
         | 
   728     protected:  | 
         | 
   729   | 
         | 
   730       virtual void erase(const Node& node) { | 
         | 
   731         _arcset.eraseNode(node);  | 
         | 
   732         Parent::erase(node);  | 
         | 
   733       }  | 
         | 
   734       virtual void erase(const std::vector<Node>& nodes) { | 
         | 
   735         for (int i = 0; i < int(nodes.size()); ++i) { | 
         | 
   736           _arcset.eraseNode(nodes[i]);  | 
         | 
   737         }  | 
         | 
   738         Parent::erase(nodes);  | 
         | 
   739       }  | 
         | 
   740       virtual void clear() { | 
         | 
   741         _arcset.clearNodes();  | 
         | 
   742         Parent::clear();  | 
         | 
   743       }  | 
         | 
   744   | 
         | 
   745     private:  | 
         | 
   746       ListEdgeSet& _arcset;  | 
         | 
   747     };  | 
         | 
   748   | 
         | 
   749     NodesImpl nodes;  | 
         | 
   750   | 
         | 
   751   public:  | 
         | 
   752   | 
         | 
   753     /// \brief Constructor of the EdgeSet.  | 
         | 
   754     ///  | 
         | 
   755     /// Constructor of the EdgeSet.  | 
         | 
   756     ListEdgeSet(const Graph& graph) : nodes(graph, *this) { | 
         | 
   757       Parent::initalize(graph, nodes);  | 
         | 
   758     }  | 
         | 
   759   | 
         | 
   760     /// \brief Add a new edge to the graph.  | 
         | 
   761     ///  | 
         | 
   762     /// Add a new edge to the graph with node \c u  | 
         | 
   763     /// and node \c v endpoints.  | 
         | 
   764     /// \return the new edge.  | 
         | 
   765     Edge addEdge(const Node& u, const Node& v) { | 
         | 
   766       return Parent::addEdge(u, v);  | 
         | 
   767     }  | 
         | 
   768   | 
         | 
   769     /// \brief Erase an edge from the graph.  | 
         | 
   770     ///  | 
         | 
   771     /// Erase the edge \c e from the graph.  | 
         | 
   772     void erase(const Edge& e) { | 
         | 
   773       return Parent::erase(e);  | 
         | 
   774     }  | 
         | 
   775   | 
         | 
   776   };  | 
         | 
   777   | 
         | 
   778   template <typename _Graph>  | 
         | 
   779   class SmartArcSetBase { | 
         | 
   780   public:  | 
         | 
   781   | 
         | 
   782     typedef _Graph Graph;  | 
         | 
   783     typedef typename Graph::Node Node;  | 
         | 
   784     typedef typename Graph::NodeIt NodeIt;  | 
         | 
   785   | 
         | 
   786   protected:  | 
         | 
   787   | 
         | 
   788     struct NodeT { | 
         | 
   789       int first_out, first_in;  | 
         | 
   790       NodeT() : first_out(-1), first_in(-1) {} | 
         | 
   791     };  | 
         | 
   792   | 
         | 
   793     typedef typename ItemSetTraits<Graph, Node>::  | 
         | 
   794     template Map<NodeT>::Type NodesImplBase;  | 
         | 
   795   | 
         | 
   796     NodesImplBase* nodes;  | 
         | 
   797   | 
         | 
   798     struct ArcT { | 
         | 
   799       Node source, target;  | 
         | 
   800       int next_out, next_in;  | 
         | 
   801       ArcT() {} | 
         | 
   802     };  | 
         | 
   803   | 
         | 
   804     std::vector<ArcT> arcs;  | 
         | 
   805   | 
         | 
   806     const Graph* graph;  | 
         | 
   807   | 
         | 
   808     void initalize(const Graph& _graph, NodesImplBase& _nodes) { | 
         | 
   809       graph = &_graph;  | 
         | 
   810       nodes = &_nodes;  | 
         | 
   811     }  | 
         | 
   812   | 
         | 
   813   public:  | 
         | 
   814   | 
         | 
   815     class Arc { | 
         | 
   816       friend class SmartArcSetBase<Graph>;  | 
         | 
   817     protected:  | 
         | 
   818       Arc(int _id) : id(_id) {} | 
         | 
   819       int id;  | 
         | 
   820     public:  | 
         | 
   821       Arc() {} | 
         | 
   822       Arc(Invalid) : id(-1) {} | 
         | 
   823       bool operator==(const Arc& arc) const { return id == arc.id; } | 
         | 
   824       bool operator!=(const Arc& arc) const { return id != arc.id; } | 
         | 
   825       bool operator<(const Arc& arc) const { return id < arc.id; } | 
         | 
   826     };  | 
         | 
   827   | 
         | 
   828     SmartArcSetBase() {} | 
         | 
   829   | 
         | 
   830     Arc addArc(const Node& u, const Node& v) { | 
         | 
   831       int n = arcs.size();  | 
         | 
   832       arcs.push_back(ArcT());  | 
         | 
   833       arcs[n].next_in = (*nodes)[v].first_in;  | 
         | 
   834       (*nodes)[v].first_in = n;  | 
         | 
   835       arcs[n].next_out = (*nodes)[u].first_out;  | 
         | 
   836       (*nodes)[u].first_out = n;  | 
         | 
   837       arcs[n].source = u;  | 
         | 
   838       arcs[n].target = v;  | 
         | 
   839       return Arc(n);  | 
         | 
   840     }  | 
         | 
   841   | 
         | 
   842     void clear() { | 
         | 
   843       Node node;  | 
         | 
   844       for (first(node); node != INVALID; next(node)) { | 
         | 
   845         (*nodes)[node].first_in = -1;  | 
         | 
   846         (*nodes)[node].first_out = -1;  | 
         | 
   847       }  | 
         | 
   848       arcs.clear();  | 
         | 
   849     }  | 
         | 
   850   | 
         | 
   851     void first(Node& node) const { | 
         | 
   852       graph->first(node);  | 
         | 
   853     }  | 
         | 
   854   | 
         | 
   855     void next(Node& node) const { | 
         | 
   856       graph->next(node);  | 
         | 
   857     }  | 
         | 
   858   | 
         | 
   859     void first(Arc& arc) const { | 
         | 
   860       arc.id = arcs.size() - 1;  | 
         | 
   861     }  | 
         | 
   862   | 
         | 
   863     void next(Arc& arc) const { | 
         | 
   864       --arc.id;  | 
         | 
   865     }  | 
         | 
   866   | 
         | 
   867     void firstOut(Arc& arc, const Node& node) const { | 
         | 
   868       arc.id = (*nodes)[node].first_out;  | 
         | 
   869     }  | 
         | 
   870   | 
         | 
   871     void nextOut(Arc& arc) const { | 
         | 
   872       arc.id = arcs[arc.id].next_out;  | 
         | 
   873     }  | 
         | 
   874   | 
         | 
   875     void firstIn(Arc& arc, const Node& node) const { | 
         | 
   876       arc.id = (*nodes)[node].first_in;  | 
         | 
   877     }  | 
         | 
   878   | 
         | 
   879     void nextIn(Arc& arc) const { | 
         | 
   880       arc.id = arcs[arc.id].next_in;  | 
         | 
   881     }  | 
         | 
   882   | 
         | 
   883     int id(const Node& node) const { return graph->id(node); } | 
         | 
   884     int id(const Arc& arc) const { return arc.id; } | 
         | 
   885   | 
         | 
   886     Node nodeFromId(int ix) const { return graph->nodeFromId(ix); } | 
         | 
   887     Arc arcFromId(int ix) const { return Arc(ix); } | 
         | 
   888   | 
         | 
   889     int maxNodeId() const { return graph->maxNodeId(); }; | 
         | 
   890     int maxArcId() const { return arcs.size() - 1; } | 
         | 
   891   | 
         | 
   892     Node source(const Arc& arc) const { return arcs[arc.id].source;} | 
         | 
   893     Node target(const Arc& arc) const { return arcs[arc.id].target;} | 
         | 
   894   | 
         | 
   895     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;  | 
         | 
   896   | 
         | 
   897     NodeNotifier& notifier(Node) const { | 
         | 
   898       return graph->notifier(Node());  | 
         | 
   899     }  | 
         | 
   900   | 
         | 
   901     template <typename _Value>  | 
         | 
   902     class NodeMap : public Graph::template NodeMap<_Value> { | 
         | 
   903     public:  | 
         | 
   904   | 
         | 
   905       typedef typename _Graph::template NodeMap<_Value> Parent;  | 
         | 
   906   | 
         | 
   907       explicit NodeMap(const SmartArcSetBase<Graph>& arcset)  | 
         | 
   908         : Parent(*arcset.graph) { } | 
         | 
   909   | 
         | 
   910       NodeMap(const SmartArcSetBase<Graph>& arcset, const _Value& value)  | 
         | 
   911         : Parent(*arcset.graph, value) { } | 
         | 
   912   | 
         | 
   913       NodeMap& operator=(const NodeMap& cmap) { | 
         | 
   914         return operator=<NodeMap>(cmap);  | 
         | 
   915       }  | 
         | 
   916   | 
         | 
   917       template <typename CMap>  | 
         | 
   918       NodeMap& operator=(const CMap& cmap) { | 
         | 
   919         Parent::operator=(cmap);  | 
         | 
   920         return *this;  | 
         | 
   921       }  | 
         | 
   922     };  | 
         | 
   923   | 
         | 
   924   };  | 
         | 
   925   | 
         | 
   926   | 
         | 
   927   /// \ingroup semi_adaptors  | 
         | 
   928   ///  | 
         | 
   929   /// \brief Digraph using a node set of another digraph or graph and  | 
         | 
   930   /// an own arc set.  | 
         | 
   931   ///  | 
         | 
   932   /// This structure can be used to establish another directed graph  | 
         | 
   933   /// over a node set of an existing one. This class uses the same  | 
         | 
   934   /// Node type as the underlying graph, and each valid node of the  | 
         | 
   935   /// original graph is valid in this arc set, therefore the node  | 
         | 
   936   /// objects of the original graph can be used directly with this  | 
         | 
   937   /// class. The node handling functions (id handling, observing, and  | 
         | 
   938   /// iterators) works equivalently as in the original graph.  | 
         | 
   939   ///  | 
         | 
   940   /// \param _Graph The type of the graph which shares its node set with  | 
         | 
   941   /// this class. Its interface must conform to the  | 
         | 
   942   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"  | 
         | 
   943   /// concept.  | 
         | 
   944   ///  | 
         | 
   945   /// This implementation is slightly faster than the \c ListArcSet,  | 
         | 
   946   /// because it uses continuous storage for arcs and it uses just  | 
         | 
   947   /// single-linked lists for enumerate outgoing and incoming  | 
         | 
   948   /// arcs. Therefore the arcs cannot be erased from the arc sets.  | 
         | 
   949   ///  | 
         | 
   950   /// \warning If a node is erased from the underlying graph and this  | 
         | 
   951   /// node is the source or target of one arc in the arc set, then  | 
         | 
   952   /// the arc set is invalidated, and it cannot be used anymore. The  | 
         | 
   953   /// validity can be checked with the \c valid() member function.  | 
         | 
   954   ///  | 
         | 
   955   /// This class is fully conform to the \ref concepts::Digraph  | 
         | 
   956   /// "Digraph" concept.  | 
         | 
   957   template <typename _Graph>  | 
         | 
   958   class SmartArcSet : public ArcSetExtender<SmartArcSetBase<_Graph> > { | 
         | 
   959   | 
         | 
   960   public:  | 
         | 
   961   | 
         | 
   962     typedef ArcSetExtender<SmartArcSetBase<_Graph> > Parent;  | 
         | 
   963   | 
         | 
   964     typedef typename Parent::Node Node;  | 
         | 
   965     typedef typename Parent::Arc Arc;  | 
         | 
   966   | 
         | 
   967     typedef _Graph Graph;  | 
         | 
   968   | 
         | 
   969   protected:  | 
         | 
   970   | 
         | 
   971     typedef typename Parent::NodesImplBase NodesImplBase;  | 
         | 
   972   | 
         | 
   973     void eraseNode(const Node& node) { | 
         | 
   974       if (typename Parent::InArcIt(*this, node) == INVALID &&  | 
         | 
   975           typename Parent::OutArcIt(*this, node) == INVALID) { | 
         | 
   976         return;  | 
         | 
   977       }  | 
         | 
   978       throw typename NodesImplBase::Notifier::ImmediateDetach();  | 
         | 
   979     }  | 
         | 
   980   | 
         | 
   981     void clearNodes() { | 
         | 
   982       Parent::clear();  | 
         | 
   983     }  | 
         | 
   984   | 
         | 
   985     class NodesImpl : public NodesImplBase { | 
         | 
   986     public:  | 
         | 
   987       typedef NodesImplBase Parent;  | 
         | 
   988   | 
         | 
   989       NodesImpl(const Graph& graph, SmartArcSet& arcset)  | 
         | 
   990         : Parent(graph), _arcset(arcset) {} | 
         | 
   991   | 
         | 
   992       virtual ~NodesImpl() {} | 
         | 
   993   | 
         | 
   994       bool attached() const { | 
         | 
   995         return Parent::attached();  | 
         | 
   996       }  | 
         | 
   997   | 
         | 
   998     protected:  | 
         | 
   999   | 
         | 
  1000       virtual void erase(const Node& node) { | 
         | 
  1001         try { | 
         | 
  1002           _arcset.eraseNode(node);  | 
         | 
  1003           Parent::erase(node);  | 
         | 
  1004         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { | 
         | 
  1005           Parent::clear();  | 
         | 
  1006           throw;  | 
         | 
  1007         }  | 
         | 
  1008       }  | 
         | 
  1009       virtual void erase(const std::vector<Node>& nodes) { | 
         | 
  1010         try { | 
         | 
  1011           for (int i = 0; i < int(nodes.size()); ++i) { | 
         | 
  1012             _arcset.eraseNode(nodes[i]);  | 
         | 
  1013           }  | 
         | 
  1014           Parent::erase(nodes);  | 
         | 
  1015         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { | 
         | 
  1016           Parent::clear();  | 
         | 
  1017           throw;  | 
         | 
  1018         }  | 
         | 
  1019       }  | 
         | 
  1020       virtual void clear() { | 
         | 
  1021         _arcset.clearNodes();  | 
         | 
  1022         Parent::clear();  | 
         | 
  1023       }  | 
         | 
  1024   | 
         | 
  1025     private:  | 
         | 
  1026       SmartArcSet& _arcset;  | 
         | 
  1027     };  | 
         | 
  1028   | 
         | 
  1029     NodesImpl nodes;  | 
         | 
  1030   | 
         | 
  1031   public:  | 
         | 
  1032   | 
         | 
  1033     /// \brief Constructor of the ArcSet.  | 
         | 
  1034     ///  | 
         | 
  1035     /// Constructor of the ArcSet.  | 
         | 
  1036     SmartArcSet(const Graph& graph) : nodes(graph, *this) { | 
         | 
  1037       Parent::initalize(graph, nodes);  | 
         | 
  1038     }  | 
         | 
  1039   | 
         | 
  1040     /// \brief Add a new arc to the digraph.  | 
         | 
  1041     ///  | 
         | 
  1042     /// Add a new arc to the digraph with source node \c s  | 
         | 
  1043     /// and target node \c t.  | 
         | 
  1044     /// \return the new arc.  | 
         | 
  1045     Arc addArc(const Node& s, const Node& t) { | 
         | 
  1046       return Parent::addArc(s, t);  | 
         | 
  1047     }  | 
         | 
  1048   | 
         | 
  1049     /// \brief Validity check  | 
         | 
  1050     ///  | 
         | 
  1051     /// This functions gives back false if the ArcSet is  | 
         | 
  1052     /// invalidated. It occurs when a node in the underlying graph is  | 
         | 
  1053     /// erased and it is not isolated in the ArcSet.  | 
         | 
  1054     bool valid() const { | 
         | 
  1055       return nodes.attached();  | 
         | 
  1056     }  | 
         | 
  1057   | 
         | 
  1058   };  | 
         | 
  1059   | 
         | 
  1060   | 
         | 
  1061   template <typename _Graph>  | 
         | 
  1062   class SmartEdgeSetBase { | 
         | 
  1063   public:  | 
         | 
  1064   | 
         | 
  1065     typedef _Graph Graph;  | 
         | 
  1066     typedef typename Graph::Node Node;  | 
         | 
  1067     typedef typename Graph::NodeIt NodeIt;  | 
         | 
  1068   | 
         | 
  1069   protected:  | 
         | 
  1070   | 
         | 
  1071     struct NodeT { | 
         | 
  1072       int first_out;  | 
         | 
  1073       NodeT() : first_out(-1) {} | 
         | 
  1074     };  | 
         | 
  1075   | 
         | 
  1076     typedef typename ItemSetTraits<Graph, Node>::  | 
         | 
  1077     template Map<NodeT>::Type NodesImplBase;  | 
         | 
  1078   | 
         | 
  1079     NodesImplBase* nodes;  | 
         | 
  1080   | 
         | 
  1081     struct ArcT { | 
         | 
  1082       Node target;  | 
         | 
  1083       int next_out;  | 
         | 
  1084       ArcT() {} | 
         | 
  1085     };  | 
         | 
  1086   | 
         | 
  1087     std::vector<ArcT> arcs;  | 
         | 
  1088   | 
         | 
  1089     const Graph* graph;  | 
         | 
  1090   | 
         | 
  1091     void initalize(const Graph& _graph, NodesImplBase& _nodes) { | 
         | 
  1092       graph = &_graph;  | 
         | 
  1093       nodes = &_nodes;  | 
         | 
  1094     }  | 
         | 
  1095   | 
         | 
  1096   public:  | 
         | 
  1097   | 
         | 
  1098     class Edge { | 
         | 
  1099       friend class SmartEdgeSetBase;  | 
         | 
  1100     protected:  | 
         | 
  1101   | 
         | 
  1102       int id;  | 
         | 
  1103       explicit Edge(int _id) { id = _id;} | 
         | 
  1104   | 
         | 
  1105     public:  | 
         | 
  1106       Edge() {} | 
         | 
  1107       Edge (Invalid) { id = -1; } | 
         | 
  1108       bool operator==(const Edge& arc) const {return id == arc.id;} | 
         | 
  1109       bool operator!=(const Edge& arc) const {return id != arc.id;} | 
         | 
  1110       bool operator<(const Edge& arc) const {return id < arc.id;} | 
         | 
  1111     };  | 
         | 
  1112   | 
         | 
  1113     class Arc { | 
         | 
  1114       friend class SmartEdgeSetBase;  | 
         | 
  1115     protected:  | 
         | 
  1116       Arc(int _id) : id(_id) {} | 
         | 
  1117       int id;  | 
         | 
  1118     public:  | 
         | 
  1119       operator Edge() const { return edgeFromId(id / 2); } | 
         | 
  1120   | 
         | 
  1121       Arc() {} | 
         | 
  1122       Arc(Invalid) : id(-1) {} | 
         | 
  1123       bool operator==(const Arc& arc) const { return id == arc.id; } | 
         | 
  1124       bool operator!=(const Arc& arc) const { return id != arc.id; } | 
         | 
  1125       bool operator<(const Arc& arc) const { return id < arc.id; } | 
         | 
  1126     };  | 
         | 
  1127   | 
         | 
  1128     SmartEdgeSetBase() {} | 
         | 
  1129   | 
         | 
  1130     Edge addEdge(const Node& u, const Node& v) { | 
         | 
  1131       int n = arcs.size();  | 
         | 
  1132       arcs.push_back(ArcT());  | 
         | 
  1133       arcs.push_back(ArcT());  | 
         | 
  1134   | 
         | 
  1135       arcs[n].target = u;  | 
         | 
  1136       arcs[n | 1].target = v;  | 
         | 
  1137   | 
         | 
  1138       arcs[n].next_out = (*nodes)[v].first_out;  | 
         | 
  1139       (*nodes)[v].first_out = n;  | 
         | 
  1140   | 
         | 
  1141       arcs[n | 1].next_out = (*nodes)[u].first_out;  | 
         | 
  1142       (*nodes)[u].first_out = (n | 1);  | 
         | 
  1143   | 
         | 
  1144       return Edge(n / 2);  | 
         | 
  1145     }  | 
         | 
  1146   | 
         | 
  1147     void clear() { | 
         | 
  1148       Node node;  | 
         | 
  1149       for (first(node); node != INVALID; next(node)) { | 
         | 
  1150         (*nodes)[node].first_out = -1;  | 
         | 
  1151       }  | 
         | 
  1152       arcs.clear();  | 
         | 
  1153     }  | 
         | 
  1154   | 
         | 
  1155     void first(Node& node) const { | 
         | 
  1156       graph->first(node);  | 
         | 
  1157     }  | 
         | 
  1158   | 
         | 
  1159     void next(Node& node) const { | 
         | 
  1160       graph->next(node);  | 
         | 
  1161     }  | 
         | 
  1162   | 
         | 
  1163     void first(Arc& arc) const { | 
         | 
  1164       arc.id = arcs.size() - 1;  | 
         | 
  1165     }  | 
         | 
  1166   | 
         | 
  1167     void next(Arc& arc) const { | 
         | 
  1168       --arc.id;  | 
         | 
  1169     }  | 
         | 
  1170   | 
         | 
  1171     void first(Edge& arc) const { | 
         | 
  1172       arc.id = arcs.size() / 2 - 1;  | 
         | 
  1173     }  | 
         | 
  1174   | 
         | 
  1175     void next(Edge& arc) const { | 
         | 
  1176       --arc.id;  | 
         | 
  1177     }  | 
         | 
  1178   | 
         | 
  1179     void firstOut(Arc& arc, const Node& node) const { | 
         | 
  1180       arc.id = (*nodes)[node].first_out;  | 
         | 
  1181     }  | 
         | 
  1182   | 
         | 
  1183     void nextOut(Arc& arc) const { | 
         | 
  1184       arc.id = arcs[arc.id].next_out;  | 
         | 
  1185     }  | 
         | 
  1186   | 
         | 
  1187     void firstIn(Arc& arc, const Node& node) const { | 
         | 
  1188       arc.id = (((*nodes)[node].first_out) ^ 1);  | 
         | 
  1189       if (arc.id == -2) arc.id = -1;  | 
         | 
  1190     }  | 
         | 
  1191   | 
         | 
  1192     void nextIn(Arc& arc) const { | 
         | 
  1193       arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);  | 
         | 
  1194       if (arc.id == -2) arc.id = -1;  | 
         | 
  1195     }  | 
         | 
  1196   | 
         | 
  1197     void firstInc(Edge &arc, bool& dir, const Node& node) const { | 
         | 
  1198       int de = (*nodes)[node].first_out;  | 
         | 
  1199       if (de != -1 ) { | 
         | 
  1200         arc.id = de / 2;  | 
         | 
  1201         dir = ((de & 1) == 1);  | 
         | 
  1202       } else { | 
         | 
  1203         arc.id = -1;  | 
         | 
  1204         dir = true;  | 
         | 
  1205       }  | 
         | 
  1206     }  | 
         | 
  1207     void nextInc(Edge &arc, bool& dir) const { | 
         | 
  1208       int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);  | 
         | 
  1209       if (de != -1 ) { | 
         | 
  1210         arc.id = de / 2;  | 
         | 
  1211         dir = ((de & 1) == 1);  | 
         | 
  1212       } else { | 
         | 
  1213         arc.id = -1;  | 
         | 
  1214         dir = true;  | 
         | 
  1215       }  | 
         | 
  1216     }  | 
         | 
  1217   | 
         | 
  1218     static bool direction(Arc arc) { | 
         | 
  1219       return (arc.id & 1) == 1;  | 
         | 
  1220     }  | 
         | 
  1221   | 
         | 
  1222     static Arc direct(Edge edge, bool dir) { | 
         | 
  1223       return Arc(edge.id * 2 + (dir ? 1 : 0));  | 
         | 
  1224     }  | 
         | 
  1225   | 
         | 
  1226     int id(Node node) const { return graph->id(node); } | 
         | 
  1227     static int id(Arc arc) { return arc.id; } | 
         | 
  1228     static int id(Edge arc) { return arc.id; } | 
         | 
  1229   | 
         | 
  1230     Node nodeFromId(int id) const { return graph->nodeFromId(id); } | 
         | 
  1231     static Arc arcFromId(int id) { return Arc(id); } | 
         | 
  1232     static Edge edgeFromId(int id) { return Edge(id);} | 
         | 
  1233   | 
         | 
  1234     int maxNodeId() const { return graph->maxNodeId(); }; | 
         | 
  1235     int maxArcId() const { return arcs.size() - 1; } | 
         | 
  1236     int maxEdgeId() const { return arcs.size() / 2 - 1; } | 
         | 
  1237   | 
         | 
  1238     Node source(Arc e) const { return arcs[e.id ^ 1].target; } | 
         | 
  1239     Node target(Arc e) const { return arcs[e.id].target; } | 
         | 
  1240   | 
         | 
  1241     Node u(Edge e) const { return arcs[2 * e.id].target; } | 
         | 
  1242     Node v(Edge e) const { return arcs[2 * e.id + 1].target; } | 
         | 
  1243   | 
         | 
  1244     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;  | 
         | 
  1245   | 
         | 
  1246     NodeNotifier& notifier(Node) const { | 
         | 
  1247       return graph->notifier(Node());  | 
         | 
  1248     }  | 
         | 
  1249   | 
         | 
  1250     template <typename _Value>  | 
         | 
  1251     class NodeMap : public Graph::template NodeMap<_Value> { | 
         | 
  1252     public:  | 
         | 
  1253   | 
         | 
  1254       typedef typename _Graph::template NodeMap<_Value> Parent;  | 
         | 
  1255   | 
         | 
  1256       explicit NodeMap(const SmartEdgeSetBase<Graph>& arcset)  | 
         | 
  1257         : Parent(*arcset.graph) { } | 
         | 
  1258   | 
         | 
  1259       NodeMap(const SmartEdgeSetBase<Graph>& arcset, const _Value& value)  | 
         | 
  1260         : Parent(*arcset.graph, value) { } | 
         | 
  1261   | 
         | 
  1262       NodeMap& operator=(const NodeMap& cmap) { | 
         | 
  1263         return operator=<NodeMap>(cmap);  | 
         | 
  1264       }  | 
         | 
  1265   | 
         | 
  1266       template <typename CMap>  | 
         | 
  1267       NodeMap& operator=(const CMap& cmap) { | 
         | 
  1268         Parent::operator=(cmap);  | 
         | 
  1269         return *this;  | 
         | 
  1270       }  | 
         | 
  1271     };  | 
         | 
  1272   | 
         | 
  1273   };  | 
         | 
  1274   | 
         | 
  1275   /// \ingroup semi_adaptors  | 
         | 
  1276   ///  | 
         | 
  1277   /// \brief Graph using a node set of another digraph or graph and an  | 
         | 
  1278   /// own edge set.  | 
         | 
  1279   ///  | 
         | 
  1280   /// This structure can be used to establish another graph over a  | 
         | 
  1281   /// node set of an existing one. This class uses the same Node type  | 
         | 
  1282   /// as the underlying graph, and each valid node of the original  | 
         | 
  1283   /// graph is valid in this arc set, therefore the node objects of  | 
         | 
  1284   /// the original graph can be used directly with this class. The  | 
         | 
  1285   /// node handling functions (id handling, observing, and iterators)  | 
         | 
  1286   /// works equivalently as in the original graph.  | 
         | 
  1287   ///  | 
         | 
  1288   /// \param _Graph The type of the graph which shares its node set  | 
         | 
  1289   /// with this class. Its interface must conform to the  | 
         | 
  1290   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"  | 
         | 
  1291   ///  concept.  | 
         | 
  1292   ///  | 
         | 
  1293   /// This implementation is slightly faster than the \c ListEdgeSet,  | 
         | 
  1294   /// because it uses continuous storage for edges and it uses just  | 
         | 
  1295   /// single-linked lists for enumerate incident edges. Therefore the  | 
         | 
  1296   /// edges cannot be erased from the edge sets.  | 
         | 
  1297   ///  | 
         | 
  1298   /// \warning If a node is erased from the underlying graph and this  | 
         | 
  1299   /// node is incident to one edge in the edge set, then the edge set  | 
         | 
  1300   /// is invalidated, and it cannot be used anymore. The validity can  | 
         | 
  1301   /// be checked with the \c valid() member function.  | 
         | 
  1302   ///  | 
         | 
  1303   /// This class is fully conform to the \ref concepts::Graph  | 
         | 
  1304   /// "Graph" concept.  | 
         | 
  1305   template <typename _Graph>  | 
         | 
  1306   class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > { | 
         | 
  1307   | 
         | 
  1308   public:  | 
         | 
  1309   | 
         | 
  1310     typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;  | 
         | 
  1311   | 
         | 
  1312     typedef typename Parent::Node Node;  | 
         | 
  1313     typedef typename Parent::Arc Arc;  | 
         | 
  1314     typedef typename Parent::Edge Edge;  | 
         | 
  1315   | 
         | 
  1316     typedef _Graph Graph;  | 
         | 
  1317   | 
         | 
  1318   protected:  | 
         | 
  1319   | 
         | 
  1320     typedef typename Parent::NodesImplBase NodesImplBase;  | 
         | 
  1321   | 
         | 
  1322     void eraseNode(const Node& node) { | 
         | 
  1323       if (typename Parent::IncEdgeIt(*this, node) == INVALID) { | 
         | 
  1324         return;  | 
         | 
  1325       }  | 
         | 
  1326       throw typename NodesImplBase::Notifier::ImmediateDetach();  | 
         | 
  1327     }  | 
         | 
  1328   | 
         | 
  1329     void clearNodes() { | 
         | 
  1330       Parent::clear();  | 
         | 
  1331     }  | 
         | 
  1332   | 
         | 
  1333     class NodesImpl : public NodesImplBase { | 
         | 
  1334     public:  | 
         | 
  1335       typedef NodesImplBase Parent;  | 
         | 
  1336   | 
         | 
  1337       NodesImpl(const Graph& graph, SmartEdgeSet& arcset)  | 
         | 
  1338         : Parent(graph), _arcset(arcset) {} | 
         | 
  1339   | 
         | 
  1340       virtual ~NodesImpl() {} | 
         | 
  1341   | 
         | 
  1342       bool attached() const { | 
         | 
  1343         return Parent::attached();  | 
         | 
  1344       }  | 
         | 
  1345   | 
         | 
  1346     protected:  | 
         | 
  1347   | 
         | 
  1348       virtual void erase(const Node& node) { | 
         | 
  1349         try { | 
         | 
  1350           _arcset.eraseNode(node);  | 
         | 
  1351           Parent::erase(node);  | 
         | 
  1352         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { | 
         | 
  1353           Parent::clear();  | 
         | 
  1354           throw;  | 
         | 
  1355         }  | 
         | 
  1356       }  | 
         | 
  1357       virtual void erase(const std::vector<Node>& nodes) { | 
         | 
  1358         try { | 
         | 
  1359           for (int i = 0; i < int(nodes.size()); ++i) { | 
         | 
  1360             _arcset.eraseNode(nodes[i]);  | 
         | 
  1361           }  | 
         | 
  1362           Parent::erase(nodes);  | 
         | 
  1363         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { | 
         | 
  1364           Parent::clear();  | 
         | 
  1365           throw;  | 
         | 
  1366         }  | 
         | 
  1367       }  | 
         | 
  1368       virtual void clear() { | 
         | 
  1369         _arcset.clearNodes();  | 
         | 
  1370         Parent::clear();  | 
         | 
  1371       }  | 
         | 
  1372   | 
         | 
  1373     private:  | 
         | 
  1374       SmartEdgeSet& _arcset;  | 
         | 
  1375     };  | 
         | 
  1376   | 
         | 
  1377     NodesImpl nodes;  | 
         | 
  1378   | 
         | 
  1379   public:  | 
         | 
  1380   | 
         | 
  1381     /// \brief Constructor of the EdgeSet.  | 
         | 
  1382     ///  | 
         | 
  1383     /// Constructor of the EdgeSet.  | 
         | 
  1384     SmartEdgeSet(const Graph& graph) : nodes(graph, *this) { | 
         | 
  1385       Parent::initalize(graph, nodes);  | 
         | 
  1386     }  | 
         | 
  1387   | 
         | 
  1388     /// \brief Add a new edge to the graph.  | 
         | 
  1389     ///  | 
         | 
  1390     /// Add a new edge to the graph with node \c u  | 
         | 
  1391     /// and node \c v endpoints.  | 
         | 
  1392     /// \return the new edge.  | 
         | 
  1393     Edge addEdge(const Node& u, const Node& v) { | 
         | 
  1394       return Parent::addEdge(u, v);  | 
         | 
  1395     }  | 
         | 
  1396   | 
         | 
  1397     /// \brief Validity check  | 
         | 
  1398     ///  | 
         | 
  1399     /// This functions gives back false if the EdgeSet is  | 
         | 
  1400     /// invalidated. It occurs when a node in the underlying graph is  | 
         | 
  1401     /// erased and it is not isolated in the EdgeSet.  | 
         | 
  1402     bool valid() const { | 
         | 
  1403       return nodes.attached();  | 
         | 
  1404     }  | 
         | 
  1405   | 
         | 
  1406   };  | 
         | 
  1407   | 
         | 
  1408 }  | 
         | 
  1409   | 
         | 
  1410 #endif  |