1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2008
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     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.
 
    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
 
    19 #ifndef LEMON_EDGE_SET_H
 
    20 #define LEMON_EDGE_SET_H
 
    22 #include <lemon/core.h>
 
    23 #include <lemon/bits/edge_set_extender.h>
 
    27 /// \brief ArcSet and EdgeSet classes.
 
    29 /// Graphs which use another graph's node-set as own.
 
    32   template <typename GR>
 
    33   class ListArcSetBase {
 
    36     typedef typename GR::Node Node;
 
    37     typedef typename GR::NodeIt NodeIt;
 
    42       int first_out, first_in;
 
    43       NodeT() : first_out(-1), first_in(-1) {}
 
    46     typedef typename ItemSetTraits<GR, Node>::
 
    47     template Map<NodeT>::Type NodesImplBase;
 
    49     NodesImplBase* _nodes;
 
    53       int next_out, next_in;
 
    54       int prev_out, prev_in;
 
    55       ArcT() : prev_out(-1), prev_in(-1) {}
 
    58     std::vector<ArcT> arcs;
 
    65     void initalize(const GR& graph, NodesImplBase& nodes) {
 
    73       friend class ListArcSetBase<GR>;
 
    75       Arc(int _id) : id(_id) {}
 
    79       Arc(Invalid) : id(-1) {}
 
    80       bool operator==(const Arc& arc) const { return id == arc.id; }
 
    81       bool operator!=(const Arc& arc) const { return id != arc.id; }
 
    82       bool operator<(const Arc& arc) const { return id < arc.id; }
 
    85     ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
 
    89         "This graph structure does not support node insertion");
 
    90       return INVALID; // avoid warning
 
    93     Arc addArc(const Node& u, const Node& v) {
 
    95       if (first_free_arc == -1) {
 
    97         arcs.push_back(ArcT());
 
   100         first_free_arc = arcs[first_free_arc].next_in;
 
   102       arcs[n].next_in = (*_nodes)[v].first_in;
 
   103       if ((*_nodes)[v].first_in != -1) {
 
   104         arcs[(*_nodes)[v].first_in].prev_in = n;
 
   106       (*_nodes)[v].first_in = n;
 
   107       arcs[n].next_out = (*_nodes)[u].first_out;
 
   108       if ((*_nodes)[u].first_out != -1) {
 
   109         arcs[(*_nodes)[u].first_out].prev_out = n;
 
   111       (*_nodes)[u].first_out = n;
 
   117     void erase(const Arc& arc) {
 
   119       if (arcs[n].prev_in != -1) {
 
   120         arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
 
   122         (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
 
   124       if (arcs[n].next_in != -1) {
 
   125         arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
 
   128       if (arcs[n].prev_out != -1) {
 
   129         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
 
   131         (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
 
   133       if (arcs[n].next_out != -1) {
 
   134         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
 
   141       for (first(node); node != INVALID; next(node)) {
 
   142         (*_nodes)[node].first_in = -1;
 
   143         (*_nodes)[node].first_out = -1;
 
   150     void first(Node& node) const {
 
   154     void next(Node& node) const {
 
   158     void first(Arc& arc) const {
 
   161       while (node != INVALID && (*_nodes)[node].first_in == -1) {
 
   164       arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
 
   167     void next(Arc& arc) const {
 
   168       if (arcs[arc.id].next_in != -1) {
 
   169         arc.id = arcs[arc.id].next_in;
 
   171         Node node = arcs[arc.id].target;
 
   173         while (node != INVALID && (*_nodes)[node].first_in == -1) {
 
   176         arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
 
   180     void firstOut(Arc& arc, const Node& node) const {
 
   181       arc.id = (*_nodes)[node].first_out;
 
   184     void nextOut(Arc& arc) const {
 
   185       arc.id = arcs[arc.id].next_out;
 
   188     void firstIn(Arc& arc, const Node& node) const {
 
   189       arc.id = (*_nodes)[node].first_in;
 
   192     void nextIn(Arc& arc) const {
 
   193       arc.id = arcs[arc.id].next_in;
 
   196     int id(const Node& node) const { return _graph->id(node); }
 
   197     int id(const Arc& arc) const { return arc.id; }
 
   199     Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
 
   200     Arc arcFromId(int ix) const { return Arc(ix); }
 
   202     int maxNodeId() const { return _graph->maxNodeId(); };
 
   203     int maxArcId() const { return arcs.size() - 1; }
 
   205     Node source(const Arc& arc) const { return arcs[arc.id].source;}
 
   206     Node target(const Arc& arc) const { return arcs[arc.id].target;}
 
   208     typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
 
   210     NodeNotifier& notifier(Node) const {
 
   211       return _graph->notifier(Node());
 
   214     template <typename V>
 
   215     class NodeMap : public GR::template NodeMap<V> {
 
   216       typedef typename GR::template NodeMap<V> Parent;
 
   220       explicit NodeMap(const ListArcSetBase<GR>& arcset)
 
   221         : Parent(*arcset._graph) {}
 
   223       NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
 
   224         : Parent(*arcset._graph, value) {}
 
   226       NodeMap& operator=(const NodeMap& cmap) {
 
   227         return operator=<NodeMap>(cmap);
 
   230       template <typename CMap>
 
   231       NodeMap& operator=(const CMap& cmap) {
 
   232         Parent::operator=(cmap);
 
   241   /// \brief Digraph using a node set of another digraph or graph and
 
   244   /// This structure can be used to establish another directed graph
 
   245   /// over a node set of an existing one. This class uses the same
 
   246   /// Node type as the underlying graph, and each valid node of the
 
   247   /// original graph is valid in this arc set, therefore the node
 
   248   /// objects of the original graph can be used directly with this
 
   249   /// class. The node handling functions (id handling, observing, and
 
   250   /// iterators) works equivalently as in the original graph.
 
   252   /// This implementation is based on doubly-linked lists, from each
 
   253   /// node the outgoing and the incoming arcs make up lists, therefore
 
   254   /// one arc can be erased in constant time. It also makes possible,
 
   255   /// that node can be removed from the underlying graph, in this case
 
   256   /// all arcs incident to the given node is erased from the arc set.
 
   258   /// This class fully conforms to the \ref concepts::Digraph
 
   259   /// "Digraph" concept.
 
   260   /// It provides only linear time counting for nodes and arcs.
 
   262   /// \param GR The type of the graph which shares its node set with
 
   263   /// this class. Its interface must conform to the
 
   264   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
 
   266   template <typename GR>
 
   267   class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
 
   268     typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
 
   272     typedef typename Parent::Node Node;
 
   273     typedef typename Parent::Arc Arc;
 
   275     typedef typename Parent::NodesImplBase NodesImplBase;
 
   277     void eraseNode(const Node& node) {
 
   279       Parent::firstOut(arc, node);
 
   280       while (arc != INVALID ) {
 
   282         Parent::firstOut(arc, node);
 
   285       Parent::firstIn(arc, node);
 
   286       while (arc != INVALID ) {
 
   288         Parent::firstIn(arc, node);
 
   296     class NodesImpl : public NodesImplBase {
 
   297       typedef NodesImplBase Parent;
 
   300       NodesImpl(const GR& graph, ListArcSet& arcset)
 
   301         : Parent(graph), _arcset(arcset) {}
 
   303       virtual ~NodesImpl() {}
 
   307       virtual void erase(const Node& node) {
 
   308         _arcset.eraseNode(node);
 
   311       virtual void erase(const std::vector<Node>& nodes) {
 
   312         for (int i = 0; i < int(nodes.size()); ++i) {
 
   313           _arcset.eraseNode(nodes[i]);
 
   315         Parent::erase(nodes);
 
   317       virtual void clear() {
 
   318         _arcset.clearNodes();
 
   330     /// \brief Constructor of the ArcSet.
 
   332     /// Constructor of the ArcSet.
 
   333     ListArcSet(const GR& graph) : _nodes(graph, *this) {
 
   334       Parent::initalize(graph, _nodes);
 
   337     /// \brief Add a new arc to the digraph.
 
   339     /// Add a new arc to the digraph with source node \c s
 
   340     /// and target node \c t.
 
   341     /// \return The new arc.
 
   342     Arc addArc(const Node& s, const Node& t) {
 
   343       return Parent::addArc(s, t);
 
   346     /// \brief Erase an arc from the digraph.
 
   348     /// Erase an arc \c a from the digraph.
 
   349     void erase(const Arc& a) {
 
   350       return Parent::erase(a);
 
   355   template <typename GR>
 
   356   class ListEdgeSetBase {
 
   359     typedef typename GR::Node Node;
 
   360     typedef typename GR::NodeIt NodeIt;
 
   366       NodeT() : first_out(-1) {}
 
   369     typedef typename ItemSetTraits<GR, Node>::
 
   370     template Map<NodeT>::Type NodesImplBase;
 
   372     NodesImplBase* _nodes;
 
   376       int prev_out, next_out;
 
   377       ArcT() : prev_out(-1), next_out(-1) {}
 
   380     std::vector<ArcT> arcs;
 
   387     void initalize(const GR& graph, NodesImplBase& nodes) {
 
   395       friend class ListEdgeSetBase;
 
   399       explicit Edge(int _id) { id = _id;}
 
   403       Edge (Invalid) { id = -1; }
 
   404       bool operator==(const Edge& arc) const {return id == arc.id;}
 
   405       bool operator!=(const Edge& arc) const {return id != arc.id;}
 
   406       bool operator<(const Edge& arc) const {return id < arc.id;}
 
   410       friend class ListEdgeSetBase;
 
   412       Arc(int _id) : id(_id) {}
 
   415       operator Edge() const { return edgeFromId(id / 2); }
 
   418       Arc(Invalid) : id(-1) {}
 
   419       bool operator==(const Arc& arc) const { return id == arc.id; }
 
   420       bool operator!=(const Arc& arc) const { return id != arc.id; }
 
   421       bool operator<(const Arc& arc) const { return id < arc.id; }
 
   424     ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
 
   428         "This graph structure does not support node insertion");
 
   429       return INVALID; // avoid warning
 
   432     Edge addEdge(const Node& u, const Node& v) {
 
   435       if (first_free_arc == -1) {
 
   437         arcs.push_back(ArcT());
 
   438         arcs.push_back(ArcT());
 
   441         first_free_arc = arcs[n].next_out;
 
   445       arcs[n | 1].target = v;
 
   447       arcs[n].next_out = (*_nodes)[v].first_out;
 
   448       if ((*_nodes)[v].first_out != -1) {
 
   449         arcs[(*_nodes)[v].first_out].prev_out = n;
 
   451       (*_nodes)[v].first_out = n;
 
   452       arcs[n].prev_out = -1;
 
   454       if ((*_nodes)[u].first_out != -1) {
 
   455         arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
 
   457       arcs[n | 1].next_out = (*_nodes)[u].first_out;
 
   458       (*_nodes)[u].first_out = (n | 1);
 
   459       arcs[n | 1].prev_out = -1;
 
   464     void erase(const Edge& arc) {
 
   467       if (arcs[n].next_out != -1) {
 
   468         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
 
   471       if (arcs[n].prev_out != -1) {
 
   472         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
 
   474         (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
 
   477       if (arcs[n | 1].next_out != -1) {
 
   478         arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
 
   481       if (arcs[n | 1].prev_out != -1) {
 
   482         arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
 
   484         (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
 
   487       arcs[n].next_out = first_free_arc;
 
   494       for (first(node); node != INVALID; next(node)) {
 
   495         (*_nodes)[node].first_out = -1;
 
   502     void first(Node& node) const {
 
   506     void next(Node& node) const {
 
   510     void first(Arc& arc) const {
 
   513       while (node != INVALID && (*_nodes)[node].first_out == -1) {
 
   516       arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
 
   519     void next(Arc& arc) const {
 
   520       if (arcs[arc.id].next_out != -1) {
 
   521         arc.id = arcs[arc.id].next_out;
 
   523         Node node = arcs[arc.id ^ 1].target;
 
   525         while(node != INVALID && (*_nodes)[node].first_out == -1) {
 
   528         arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
 
   532     void first(Edge& edge) const {
 
   535       while (node != INVALID) {
 
   536         edge.id = (*_nodes)[node].first_out;
 
   537         while ((edge.id & 1) != 1) {
 
   538           edge.id = arcs[edge.id].next_out;
 
   549     void next(Edge& edge) const {
 
   550       Node node = arcs[edge.id * 2].target;
 
   551       edge.id = arcs[(edge.id * 2) | 1].next_out;
 
   552       while ((edge.id & 1) != 1) {
 
   553         edge.id = arcs[edge.id].next_out;
 
   560       while (node != INVALID) {
 
   561         edge.id = (*_nodes)[node].first_out;
 
   562         while ((edge.id & 1) != 1) {
 
   563           edge.id = arcs[edge.id].next_out;
 
   574     void firstOut(Arc& arc, const Node& node) const {
 
   575       arc.id = (*_nodes)[node].first_out;
 
   578     void nextOut(Arc& arc) const {
 
   579       arc.id = arcs[arc.id].next_out;
 
   582     void firstIn(Arc& arc, const Node& node) const {
 
   583       arc.id = (((*_nodes)[node].first_out) ^ 1);
 
   584       if (arc.id == -2) arc.id = -1;
 
   587     void nextIn(Arc& arc) const {
 
   588       arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
 
   589       if (arc.id == -2) arc.id = -1;
 
   592     void firstInc(Edge &arc, bool& dir, const Node& node) const {
 
   593       int de = (*_nodes)[node].first_out;
 
   596         dir = ((de & 1) == 1);
 
   602     void nextInc(Edge &arc, bool& dir) const {
 
   603       int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
 
   606         dir = ((de & 1) == 1);
 
   613     static bool direction(Arc arc) {
 
   614       return (arc.id & 1) == 1;
 
   617     static Arc direct(Edge edge, bool dir) {
 
   618       return Arc(edge.id * 2 + (dir ? 1 : 0));
 
   621     int id(const Node& node) const { return _graph->id(node); }
 
   622     static int id(Arc e) { return e.id; }
 
   623     static int id(Edge e) { return e.id; }
 
   625     Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
 
   626     static Arc arcFromId(int id) { return Arc(id);}
 
   627     static Edge edgeFromId(int id) { return Edge(id);}
 
   629     int maxNodeId() const { return _graph->maxNodeId(); };
 
   630     int maxEdgeId() const { return arcs.size() / 2 - 1; }
 
   631     int maxArcId() const { return arcs.size()-1; }
 
   633     Node source(Arc e) const { return arcs[e.id ^ 1].target; }
 
   634     Node target(Arc e) const { return arcs[e.id].target; }
 
   636     Node u(Edge e) const { return arcs[2 * e.id].target; }
 
   637     Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
 
   639     typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
 
   641     NodeNotifier& notifier(Node) const {
 
   642       return _graph->notifier(Node());
 
   645     template <typename V>
 
   646     class NodeMap : public GR::template NodeMap<V> {
 
   647       typedef typename GR::template NodeMap<V> Parent;
 
   651       explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
 
   652         : Parent(*arcset._graph) {}
 
   654       NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
 
   655         : Parent(*arcset._graph, value) {}
 
   657       NodeMap& operator=(const NodeMap& cmap) {
 
   658         return operator=<NodeMap>(cmap);
 
   661       template <typename CMap>
 
   662       NodeMap& operator=(const CMap& cmap) {
 
   663         Parent::operator=(cmap);
 
   672   /// \brief Graph using a node set of another digraph or graph and an
 
   675   /// This structure can be used to establish another graph over a
 
   676   /// node set of an existing one. This class uses the same Node type
 
   677   /// as the underlying graph, and each valid node of the original
 
   678   /// graph is valid in this arc set, therefore the node objects of
 
   679   /// the original graph can be used directly with this class. The
 
   680   /// node handling functions (id handling, observing, and iterators)
 
   681   /// works equivalently as in the original graph.
 
   683   /// This implementation is based on doubly-linked lists, from each
 
   684   /// node the incident edges make up lists, therefore one edge can be
 
   685   /// erased in constant time. It also makes possible, that node can
 
   686   /// be removed from the underlying graph, in this case all edges
 
   687   /// incident to the given node is erased from the arc set.
 
   689   /// This class fully conforms to the \ref concepts::Graph "Graph"
 
   691   /// It provides only linear time counting for nodes, edges and arcs.
 
   693   /// \param GR The type of the graph which shares its node set
 
   694   /// with this class. Its interface must conform to the
 
   695   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
 
   697   template <typename GR>
 
   698   class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
 
   699     typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
 
   703     typedef typename Parent::Node Node;
 
   704     typedef typename Parent::Arc Arc;
 
   705     typedef typename Parent::Edge Edge;
 
   707     typedef typename Parent::NodesImplBase NodesImplBase;
 
   709     void eraseNode(const Node& node) {
 
   711       Parent::firstOut(arc, node);
 
   712       while (arc != INVALID ) {
 
   714         Parent::firstOut(arc, node);
 
   723     class NodesImpl : public NodesImplBase {
 
   724       typedef NodesImplBase Parent;
 
   727       NodesImpl(const GR& graph, ListEdgeSet& arcset)
 
   728         : Parent(graph), _arcset(arcset) {}
 
   730       virtual ~NodesImpl() {}
 
   734       virtual void erase(const Node& node) {
 
   735         _arcset.eraseNode(node);
 
   738       virtual void erase(const std::vector<Node>& nodes) {
 
   739         for (int i = 0; i < int(nodes.size()); ++i) {
 
   740           _arcset.eraseNode(nodes[i]);
 
   742         Parent::erase(nodes);
 
   744       virtual void clear() {
 
   745         _arcset.clearNodes();
 
   750       ListEdgeSet& _arcset;
 
   757     /// \brief Constructor of the EdgeSet.
 
   759     /// Constructor of the EdgeSet.
 
   760     ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
 
   761       Parent::initalize(graph, _nodes);
 
   764     /// \brief Add a new edge to the graph.
 
   766     /// Add a new edge to the graph with node \c u
 
   767     /// and node \c v endpoints.
 
   768     /// \return The new edge.
 
   769     Edge addEdge(const Node& u, const Node& v) {
 
   770       return Parent::addEdge(u, v);
 
   773     /// \brief Erase an edge from the graph.
 
   775     /// Erase the edge \c e from the graph.
 
   776     void erase(const Edge& e) {
 
   777       return Parent::erase(e);
 
   782   template <typename GR>
 
   783   class SmartArcSetBase {
 
   786     typedef typename GR::Node Node;
 
   787     typedef typename GR::NodeIt NodeIt;
 
   792       int first_out, first_in;
 
   793       NodeT() : first_out(-1), first_in(-1) {}
 
   796     typedef typename ItemSetTraits<GR, Node>::
 
   797     template Map<NodeT>::Type NodesImplBase;
 
   799     NodesImplBase* _nodes;
 
   803       int next_out, next_in;
 
   807     std::vector<ArcT> arcs;
 
   811     void initalize(const GR& graph, NodesImplBase& nodes) {
 
   819       friend class SmartArcSetBase<GR>;
 
   821       Arc(int _id) : id(_id) {}
 
   825       Arc(Invalid) : id(-1) {}
 
   826       bool operator==(const Arc& arc) const { return id == arc.id; }
 
   827       bool operator!=(const Arc& arc) const { return id != arc.id; }
 
   828       bool operator<(const Arc& arc) const { return id < arc.id; }
 
   835         "This graph structure does not support node insertion");
 
   836       return INVALID; // avoid warning
 
   839     Arc addArc(const Node& u, const Node& v) {
 
   841       arcs.push_back(ArcT());
 
   842       arcs[n].next_in = (*_nodes)[v].first_in;
 
   843       (*_nodes)[v].first_in = n;
 
   844       arcs[n].next_out = (*_nodes)[u].first_out;
 
   845       (*_nodes)[u].first_out = n;
 
   853       for (first(node); node != INVALID; next(node)) {
 
   854         (*_nodes)[node].first_in = -1;
 
   855         (*_nodes)[node].first_out = -1;
 
   860     void first(Node& node) const {
 
   864     void next(Node& node) const {
 
   868     void first(Arc& arc) const {
 
   869       arc.id = arcs.size() - 1;
 
   872     static void next(Arc& arc) {
 
   876     void firstOut(Arc& arc, const Node& node) const {
 
   877       arc.id = (*_nodes)[node].first_out;
 
   880     void nextOut(Arc& arc) const {
 
   881       arc.id = arcs[arc.id].next_out;
 
   884     void firstIn(Arc& arc, const Node& node) const {
 
   885       arc.id = (*_nodes)[node].first_in;
 
   888     void nextIn(Arc& arc) const {
 
   889       arc.id = arcs[arc.id].next_in;
 
   892     int id(const Node& node) const { return _graph->id(node); }
 
   893     int id(const Arc& arc) const { return arc.id; }
 
   895     Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
 
   896     Arc arcFromId(int ix) const { return Arc(ix); }
 
   898     int maxNodeId() const { return _graph->maxNodeId(); };
 
   899     int maxArcId() const { return arcs.size() - 1; }
 
   901     Node source(const Arc& arc) const { return arcs[arc.id].source;}
 
   902     Node target(const Arc& arc) const { return arcs[arc.id].target;}
 
   904     typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
 
   906     NodeNotifier& notifier(Node) const {
 
   907       return _graph->notifier(Node());
 
   910     template <typename V>
 
   911     class NodeMap : public GR::template NodeMap<V> {
 
   912       typedef typename GR::template NodeMap<V> Parent;
 
   916       explicit NodeMap(const SmartArcSetBase<GR>& arcset)
 
   917         : Parent(*arcset._graph) { }
 
   919       NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
 
   920         : Parent(*arcset._graph, value) { }
 
   922       NodeMap& operator=(const NodeMap& cmap) {
 
   923         return operator=<NodeMap>(cmap);
 
   926       template <typename CMap>
 
   927       NodeMap& operator=(const CMap& cmap) {
 
   928         Parent::operator=(cmap);
 
   938   /// \brief Digraph using a node set of another digraph or graph and
 
   941   /// This structure can be used to establish another directed graph
 
   942   /// over a node set of an existing one. This class uses the same
 
   943   /// Node type as the underlying graph, and each valid node of the
 
   944   /// original graph is valid in this arc set, therefore the node
 
   945   /// objects of the original graph can be used directly with this
 
   946   /// class. The node handling functions (id handling, observing, and
 
   947   /// iterators) works equivalently as in the original graph.
 
   949   /// \param GR The type of the graph which shares its node set with
 
   950   /// this class. Its interface must conform to the
 
   951   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
 
   954   /// This implementation is slightly faster than the \c ListArcSet,
 
   955   /// because it uses continuous storage for arcs and it uses just
 
   956   /// single-linked lists for enumerate outgoing and incoming
 
   957   /// arcs. Therefore the arcs cannot be erased from the arc sets.
 
   959   /// This class fully conforms to the \ref concepts::Digraph "Digraph"
 
   961   /// It provides only linear time counting for nodes and arcs.
 
   963   /// \warning If a node is erased from the underlying graph and this
 
   964   /// node is the source or target of one arc in the arc set, then
 
   965   /// the arc set is invalidated, and it cannot be used anymore. The
 
   966   /// validity can be checked with the \c valid() member function.
 
   967   template <typename GR>
 
   968   class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
 
   969     typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
 
   973     typedef typename Parent::Node Node;
 
   974     typedef typename Parent::Arc Arc;
 
   978     typedef typename Parent::NodesImplBase NodesImplBase;
 
   980     void eraseNode(const Node& node) {
 
   981       if (typename Parent::InArcIt(*this, node) == INVALID &&
 
   982           typename Parent::OutArcIt(*this, node) == INVALID) {
 
   985       throw typename NodesImplBase::Notifier::ImmediateDetach();
 
   992     class NodesImpl : public NodesImplBase {
 
   993       typedef NodesImplBase Parent;
 
   996       NodesImpl(const GR& graph, SmartArcSet& arcset)
 
   997         : Parent(graph), _arcset(arcset) {}
 
   999       virtual ~NodesImpl() {}
 
  1001       bool attached() const {
 
  1002         return Parent::attached();
 
  1007       virtual void erase(const Node& node) {
 
  1009           _arcset.eraseNode(node);
 
  1010           Parent::erase(node);
 
  1011         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1016       virtual void erase(const std::vector<Node>& nodes) {
 
  1018           for (int i = 0; i < int(nodes.size()); ++i) {
 
  1019             _arcset.eraseNode(nodes[i]);
 
  1021           Parent::erase(nodes);
 
  1022         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1027       virtual void clear() {
 
  1028         _arcset.clearNodes();
 
  1033       SmartArcSet& _arcset;
 
  1040     /// \brief Constructor of the ArcSet.
 
  1042     /// Constructor of the ArcSet.
 
  1043     SmartArcSet(const GR& graph) : _nodes(graph, *this) {
 
  1044       Parent::initalize(graph, _nodes);
 
  1047     /// \brief Add a new arc to the digraph.
 
  1049     /// Add a new arc to the digraph with source node \c s
 
  1050     /// and target node \c t.
 
  1051     /// \return The new arc.
 
  1052     Arc addArc(const Node& s, const Node& t) {
 
  1053       return Parent::addArc(s, t);
 
  1056     /// \brief Validity check
 
  1058     /// This functions gives back false if the ArcSet is
 
  1059     /// invalidated. It occurs when a node in the underlying graph is
 
  1060     /// erased and it is not isolated in the ArcSet.
 
  1061     bool valid() const {
 
  1062       return _nodes.attached();
 
  1068   template <typename GR>
 
  1069   class SmartEdgeSetBase {
 
  1072     typedef typename GR::Node Node;
 
  1073     typedef typename GR::NodeIt NodeIt;
 
  1079       NodeT() : first_out(-1) {}
 
  1082     typedef typename ItemSetTraits<GR, Node>::
 
  1083     template Map<NodeT>::Type NodesImplBase;
 
  1085     NodesImplBase* _nodes;
 
  1093     std::vector<ArcT> arcs;
 
  1097     void initalize(const GR& graph, NodesImplBase& nodes) {
 
  1105       friend class SmartEdgeSetBase;
 
  1109       explicit Edge(int _id) { id = _id;}
 
  1113       Edge (Invalid) { id = -1; }
 
  1114       bool operator==(const Edge& arc) const {return id == arc.id;}
 
  1115       bool operator!=(const Edge& arc) const {return id != arc.id;}
 
  1116       bool operator<(const Edge& arc) const {return id < arc.id;}
 
  1120       friend class SmartEdgeSetBase;
 
  1122       Arc(int _id) : id(_id) {}
 
  1125       operator Edge() const { return edgeFromId(id / 2); }
 
  1128       Arc(Invalid) : id(-1) {}
 
  1129       bool operator==(const Arc& arc) const { return id == arc.id; }
 
  1130       bool operator!=(const Arc& arc) const { return id != arc.id; }
 
  1131       bool operator<(const Arc& arc) const { return id < arc.id; }
 
  1134     SmartEdgeSetBase() {}
 
  1138         "This graph structure does not support node insertion");
 
  1139       return INVALID; // avoid warning
 
  1142     Edge addEdge(const Node& u, const Node& v) {
 
  1143       int n = arcs.size();
 
  1144       arcs.push_back(ArcT());
 
  1145       arcs.push_back(ArcT());
 
  1148       arcs[n | 1].target = v;
 
  1150       arcs[n].next_out = (*_nodes)[v].first_out;
 
  1151       (*_nodes)[v].first_out = n;
 
  1153       arcs[n | 1].next_out = (*_nodes)[u].first_out;
 
  1154       (*_nodes)[u].first_out = (n | 1);
 
  1161       for (first(node); node != INVALID; next(node)) {
 
  1162         (*_nodes)[node].first_out = -1;
 
  1167     void first(Node& node) const {
 
  1168       _graph->first(node);
 
  1171     void next(Node& node) const {
 
  1175     void first(Arc& arc) const {
 
  1176       arc.id = arcs.size() - 1;
 
  1179     static void next(Arc& arc) {
 
  1183     void first(Edge& arc) const {
 
  1184       arc.id = arcs.size() / 2 - 1;
 
  1187     static void next(Edge& arc) {
 
  1191     void firstOut(Arc& arc, const Node& node) const {
 
  1192       arc.id = (*_nodes)[node].first_out;
 
  1195     void nextOut(Arc& arc) const {
 
  1196       arc.id = arcs[arc.id].next_out;
 
  1199     void firstIn(Arc& arc, const Node& node) const {
 
  1200       arc.id = (((*_nodes)[node].first_out) ^ 1);
 
  1201       if (arc.id == -2) arc.id = -1;
 
  1204     void nextIn(Arc& arc) const {
 
  1205       arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
 
  1206       if (arc.id == -2) arc.id = -1;
 
  1209     void firstInc(Edge &arc, bool& dir, const Node& node) const {
 
  1210       int de = (*_nodes)[node].first_out;
 
  1213         dir = ((de & 1) == 1);
 
  1219     void nextInc(Edge &arc, bool& dir) const {
 
  1220       int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
 
  1223         dir = ((de & 1) == 1);
 
  1230     static bool direction(Arc arc) {
 
  1231       return (arc.id & 1) == 1;
 
  1234     static Arc direct(Edge edge, bool dir) {
 
  1235       return Arc(edge.id * 2 + (dir ? 1 : 0));
 
  1238     int id(Node node) const { return _graph->id(node); }
 
  1239     static int id(Arc arc) { return arc.id; }
 
  1240     static int id(Edge arc) { return arc.id; }
 
  1242     Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
 
  1243     static Arc arcFromId(int id) { return Arc(id); }
 
  1244     static Edge edgeFromId(int id) { return Edge(id);}
 
  1246     int maxNodeId() const { return _graph->maxNodeId(); };
 
  1247     int maxArcId() const { return arcs.size() - 1; }
 
  1248     int maxEdgeId() const { return arcs.size() / 2 - 1; }
 
  1250     Node source(Arc e) const { return arcs[e.id ^ 1].target; }
 
  1251     Node target(Arc e) const { return arcs[e.id].target; }
 
  1253     Node u(Edge e) const { return arcs[2 * e.id].target; }
 
  1254     Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
 
  1256     typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
 
  1258     NodeNotifier& notifier(Node) const {
 
  1259       return _graph->notifier(Node());
 
  1262     template <typename V>
 
  1263     class NodeMap : public GR::template NodeMap<V> {
 
  1264       typedef typename GR::template NodeMap<V> Parent;
 
  1268       explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
 
  1269         : Parent(*arcset._graph) { }
 
  1271       NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
 
  1272         : Parent(*arcset._graph, value) { }
 
  1274       NodeMap& operator=(const NodeMap& cmap) {
 
  1275         return operator=<NodeMap>(cmap);
 
  1278       template <typename CMap>
 
  1279       NodeMap& operator=(const CMap& cmap) {
 
  1280         Parent::operator=(cmap);
 
  1289   /// \brief Graph using a node set of another digraph or graph and an
 
  1292   /// This structure can be used to establish another graph over a
 
  1293   /// node set of an existing one. This class uses the same Node type
 
  1294   /// as the underlying graph, and each valid node of the original
 
  1295   /// graph is valid in this arc set, therefore the node objects of
 
  1296   /// the original graph can be used directly with this class. The
 
  1297   /// node handling functions (id handling, observing, and iterators)
 
  1298   /// works equivalently as in the original graph.
 
  1300   /// \param GR The type of the graph which shares its node set
 
  1301   /// with this class. Its interface must conform to the
 
  1302   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
 
  1305   /// This implementation is slightly faster than the \c ListEdgeSet,
 
  1306   /// because it uses continuous storage for edges and it uses just
 
  1307   /// single-linked lists for enumerate incident edges. Therefore the
 
  1308   /// edges cannot be erased from the edge sets.
 
  1310   /// This class fully conforms to the \ref concepts::Graph "Graph"
 
  1312   /// It provides only linear time counting for nodes, edges and arcs.
 
  1314   /// \warning If a node is erased from the underlying graph and this
 
  1315   /// node is incident to one edge in the edge set, then the edge set
 
  1316   /// is invalidated, and it cannot be used anymore. The validity can
 
  1317   /// be checked with the \c valid() member function.
 
  1318   template <typename GR>
 
  1319   class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
 
  1320     typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
 
  1324     typedef typename Parent::Node Node;
 
  1325     typedef typename Parent::Arc Arc;
 
  1326     typedef typename Parent::Edge Edge;
 
  1330     typedef typename Parent::NodesImplBase NodesImplBase;
 
  1332     void eraseNode(const Node& node) {
 
  1333       if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
 
  1336       throw typename NodesImplBase::Notifier::ImmediateDetach();
 
  1343     class NodesImpl : public NodesImplBase {
 
  1344       typedef NodesImplBase Parent;
 
  1347       NodesImpl(const GR& graph, SmartEdgeSet& arcset)
 
  1348         : Parent(graph), _arcset(arcset) {}
 
  1350       virtual ~NodesImpl() {}
 
  1352       bool attached() const {
 
  1353         return Parent::attached();
 
  1358       virtual void erase(const Node& node) {
 
  1360           _arcset.eraseNode(node);
 
  1361           Parent::erase(node);
 
  1362         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1367       virtual void erase(const std::vector<Node>& nodes) {
 
  1369           for (int i = 0; i < int(nodes.size()); ++i) {
 
  1370             _arcset.eraseNode(nodes[i]);
 
  1372           Parent::erase(nodes);
 
  1373         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1378       virtual void clear() {
 
  1379         _arcset.clearNodes();
 
  1384       SmartEdgeSet& _arcset;
 
  1391     /// \brief Constructor of the EdgeSet.
 
  1393     /// Constructor of the EdgeSet.
 
  1394     SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
 
  1395       Parent::initalize(graph, _nodes);
 
  1398     /// \brief Add a new edge to the graph.
 
  1400     /// Add a new edge to the graph with node \c u
 
  1401     /// and node \c v endpoints.
 
  1402     /// \return The new edge.
 
  1403     Edge addEdge(const Node& u, const Node& v) {
 
  1404       return Parent::addEdge(u, v);
 
  1407     /// \brief Validity check
 
  1409     /// This functions gives back false if the EdgeSet is
 
  1410     /// invalidated. It occurs when a node in the underlying graph is
 
  1411     /// erased and it is not isolated in the EdgeSet.
 
  1412     bool valid() const {
 
  1413       return _nodes.attached();