lemon/edge_set.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 608 6ac5d9ae1d3d
parent 468 68fe66e2b34a
child 559 c5fd2d996909
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
     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 GR>
    33   class ListArcSetBase {
    34   public:
    35 
    36     typedef GR Graph;
    37     typedef typename GR::Node Node;
    38     typedef typename GR::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<GR, 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 GR* _graph;
    65 
    66     void initalize(const GR& graph, NodesImplBase& nodes) {
    67       _graph = &graph;
    68       _nodes = &nodes;
    69     }
    70 
    71   public:
    72 
    73     class Arc {
    74       friend class ListArcSetBase<GR>;
    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<GR, Node>::ItemNotifier NodeNotifier;
   204 
   205     NodeNotifier& notifier(Node) const {
   206       return _graph->notifier(Node());
   207     }
   208 
   209     template <typename V>
   210     class NodeMap : public GR::template NodeMap<V> {
   211     public:
   212 
   213       typedef typename GR::template NodeMap<V> Parent;
   214 
   215       explicit NodeMap(const ListArcSetBase<GR>& arcset)
   216         : Parent(*arcset._graph) {}
   217 
   218       NodeMap(const ListArcSetBase<GR>& arcset, const V& 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 GR 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 GR>
   261   class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
   262 
   263   public:
   264 
   265     typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
   266 
   267     typedef typename Parent::Node Node;
   268     typedef typename Parent::Arc Arc;
   269 
   270     typedef GR 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 GR& 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 GR& 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 GR>
   354   class ListEdgeSetBase {
   355   public:
   356 
   357     typedef GR Graph;
   358     typedef typename GR::Node Node;
   359     typedef typename GR::NodeIt NodeIt;
   360 
   361   protected:
   362 
   363     struct NodeT {
   364       int first_out;
   365       NodeT() : first_out(-1) {}
   366     };
   367 
   368     typedef typename ItemSetTraits<GR, 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 GR* _graph;
   385 
   386     void initalize(const GR& 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<GR, Node>::ItemNotifier NodeNotifier;
   633 
   634     NodeNotifier& notifier(Node) const {
   635       return _graph->notifier(Node());
   636     }
   637 
   638     template <typename V>
   639     class NodeMap : public GR::template NodeMap<V> {
   640     public:
   641 
   642       typedef typename GR::template NodeMap<V> Parent;
   643 
   644       explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
   645         : Parent(*arcset._graph) {}
   646 
   647       NodeMap(const ListEdgeSetBase<GR>& arcset, const V& 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 GR 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 GR>
   690   class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
   691 
   692   public:
   693 
   694     typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
   695 
   696     typedef typename Parent::Node Node;
   697     typedef typename Parent::Arc Arc;
   698     typedef typename Parent::Edge Edge;
   699 
   700     typedef GR 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 GR& 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 GR& 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 GR>
   779   class SmartArcSetBase {
   780   public:
   781 
   782     typedef GR 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<GR, 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 GR* _graph;
   807 
   808     void initalize(const GR& graph, NodesImplBase& nodes) {
   809       _graph = &graph;
   810       _nodes = &nodes;
   811     }
   812 
   813   public:
   814 
   815     class Arc {
   816       friend class SmartArcSetBase<GR>;
   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<GR, Node>::ItemNotifier NodeNotifier;
   896 
   897     NodeNotifier& notifier(Node) const {
   898       return _graph->notifier(Node());
   899     }
   900 
   901     template <typename V>
   902     class NodeMap : public GR::template NodeMap<V> {
   903     public:
   904 
   905       typedef typename GR::template NodeMap<V> Parent;
   906 
   907       explicit NodeMap(const SmartArcSetBase<GR>& arcset)
   908         : Parent(*arcset._graph) { }
   909 
   910       NodeMap(const SmartArcSetBase<GR>& arcset, const V& 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 GR 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 GR>
   958   class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
   959 
   960   public:
   961 
   962     typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
   963 
   964     typedef typename Parent::Node Node;
   965     typedef typename Parent::Arc Arc;
   966 
   967     typedef GR 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 GR& 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 GR& 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 GR>
  1062   class SmartEdgeSetBase {
  1063   public:
  1064 
  1065     typedef GR Graph;
  1066     typedef typename GR::Node Node;
  1067     typedef typename GR::NodeIt NodeIt;
  1068 
  1069   protected:
  1070 
  1071     struct NodeT {
  1072       int first_out;
  1073       NodeT() : first_out(-1) {}
  1074     };
  1075 
  1076     typedef typename ItemSetTraits<GR, 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 GR* _graph;
  1090 
  1091     void initalize(const GR& 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<GR, Node>::ItemNotifier NodeNotifier;
  1245 
  1246     NodeNotifier& notifier(Node) const {
  1247       return _graph->notifier(Node());
  1248     }
  1249 
  1250     template <typename V>
  1251     class NodeMap : public GR::template NodeMap<V> {
  1252     public:
  1253 
  1254       typedef typename GR::template NodeMap<V> Parent;
  1255 
  1256       explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
  1257         : Parent(*arcset._graph) { }
  1258 
  1259       NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& 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 GR 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 GR>
  1306   class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
  1307 
  1308   public:
  1309 
  1310     typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
  1311 
  1312     typedef typename Parent::Node Node;
  1313     typedef typename Parent::Arc Arc;
  1314     typedef typename Parent::Edge Edge;
  1315 
  1316     typedef GR 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 GR& 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 GR& 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