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>
 
    25 /// \ingroup semi_adaptors
 
    27 /// \brief ArcSet and EdgeSet classes.
 
    29 /// Graphs which use another graph's node-set as own.
 
    32   template <typename _Graph>
 
    33   class ListArcSetBase {
 
    37     typedef typename Graph::Node Node;
 
    38     typedef typename Graph::NodeIt NodeIt;
 
    43       int first_out, first_in;
 
    44       NodeT() : first_out(-1), first_in(-1) {}
 
    47     typedef typename ItemSetTraits<Graph, Node>::
 
    48     template Map<NodeT>::Type NodesImplBase;
 
    54       int next_out, next_in;
 
    55       int prev_out, prev_in;
 
    56       ArcT() : prev_out(-1), prev_in(-1) {}
 
    59     std::vector<ArcT> arcs;
 
    66     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
 
    74       friend class ListArcSetBase<Graph>;
 
    76       Arc(int _id) : id(_id) {}
 
    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; }
 
    86     ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
 
    88     Arc addArc(const Node& u, const Node& v) {
 
    90       if (first_free_arc == -1) {
 
    92         arcs.push_back(ArcT());
 
    95         first_free_arc = arcs[first_free_arc].next_in;
 
    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;
 
   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;
 
   106       (*nodes)[u].first_out = n;
 
   112     void erase(const Arc& arc) {
 
   114       if (arcs[n].prev_in != -1) {
 
   115         arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
 
   117         (*nodes)[arcs[n].target].first_in = arcs[n].next_in;
 
   119       if (arcs[n].next_in != -1) {
 
   120         arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
 
   123       if (arcs[n].prev_out != -1) {
 
   124         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
 
   126         (*nodes)[arcs[n].source].first_out = arcs[n].next_out;
 
   128       if (arcs[n].next_out != -1) {
 
   129         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
 
   136       for (first(node); node != INVALID; next(node)) {
 
   137         (*nodes)[node].first_in = -1;
 
   138         (*nodes)[node].first_out = -1;
 
   145     void first(Node& node) const {
 
   149     void next(Node& node) const {
 
   153     void first(Arc& arc) const {
 
   156       while (node != INVALID && (*nodes)[node].first_in == -1) {
 
   159       arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
 
   162     void next(Arc& arc) const {
 
   163       if (arcs[arc.id].next_in != -1) {
 
   164         arc.id = arcs[arc.id].next_in;
 
   166         Node node = arcs[arc.id].target;
 
   168         while (node != INVALID && (*nodes)[node].first_in == -1) {
 
   171         arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
 
   175     void firstOut(Arc& arc, const Node& node) const {
 
   176       arc.id = (*nodes)[node].first_out;
 
   179     void nextOut(Arc& arc) const {
 
   180       arc.id = arcs[arc.id].next_out;
 
   183     void firstIn(Arc& arc, const Node& node) const {
 
   184       arc.id = (*nodes)[node].first_in;
 
   187     void nextIn(Arc& arc) const {
 
   188       arc.id = arcs[arc.id].next_in;
 
   191     int id(const Node& node) const { return graph->id(node); }
 
   192     int id(const Arc& arc) const { return arc.id; }
 
   194     Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
 
   195     Arc arcFromId(int ix) const { return Arc(ix); }
 
   197     int maxNodeId() const { return graph->maxNodeId(); };
 
   198     int maxArcId() const { return arcs.size() - 1; }
 
   200     Node source(const Arc& arc) const { return arcs[arc.id].source;}
 
   201     Node target(const Arc& arc) const { return arcs[arc.id].target;}
 
   203     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
 
   205     NodeNotifier& notifier(Node) const {
 
   206       return graph->notifier(Node());
 
   209     template <typename _Value>
 
   210     class NodeMap : public Graph::template NodeMap<_Value> {
 
   213       typedef typename _Graph::template NodeMap<_Value> Parent;
 
   215       explicit NodeMap(const ListArcSetBase<Graph>& arcset)
 
   216         : Parent(*arcset.graph) {}
 
   218       NodeMap(const ListArcSetBase<Graph>& arcset, const _Value& value)
 
   219         : Parent(*arcset.graph, value) {}
 
   221       NodeMap& operator=(const NodeMap& cmap) {
 
   222         return operator=<NodeMap>(cmap);
 
   225       template <typename CMap>
 
   226       NodeMap& operator=(const CMap& cmap) {
 
   227         Parent::operator=(cmap);
 
   234   /// \ingroup semi_adaptors
 
   236   /// \brief Digraph using a node set of another digraph or graph and
 
   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.
 
   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.
 
   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"
 
   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> > {
 
   265     typedef ArcSetExtender<ListArcSetBase<_Graph> > Parent;
 
   267     typedef typename Parent::Node Node;
 
   268     typedef typename Parent::Arc Arc;
 
   270     typedef _Graph Graph;
 
   273     typedef typename Parent::NodesImplBase NodesImplBase;
 
   275     void eraseNode(const Node& node) {
 
   277       Parent::firstOut(arc, node);
 
   278       while (arc != INVALID ) {
 
   280         Parent::firstOut(arc, node);
 
   283       Parent::firstIn(arc, node);
 
   284       while (arc != INVALID ) {
 
   286         Parent::firstIn(arc, node);
 
   294     class NodesImpl : public NodesImplBase {
 
   296       typedef NodesImplBase Parent;
 
   298       NodesImpl(const Graph& graph, ListArcSet& arcset)
 
   299         : Parent(graph), _arcset(arcset) {}
 
   301       virtual ~NodesImpl() {}
 
   305       virtual void erase(const Node& node) {
 
   306         _arcset.eraseNode(node);
 
   309       virtual void erase(const std::vector<Node>& nodes) {
 
   310         for (int i = 0; i < int(nodes.size()); ++i) {
 
   311           _arcset.eraseNode(nodes[i]);
 
   313         Parent::erase(nodes);
 
   315       virtual void clear() {
 
   316         _arcset.clearNodes();
 
   328     /// \brief Constructor of the ArcSet.
 
   330     /// Constructor of the ArcSet.
 
   331     ListArcSet(const Graph& graph) : nodes(graph, *this) {
 
   332       Parent::initalize(graph, nodes);
 
   335     /// \brief Add a new arc to the digraph.
 
   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);
 
   344     /// \brief Erase an arc from the digraph.
 
   346     /// Erase an arc \c a from the digraph.
 
   347     void erase(const Arc& a) {
 
   348       return Parent::erase(a);
 
   353   template <typename _Graph>
 
   354   class ListEdgeSetBase {
 
   357     typedef _Graph Graph;
 
   358     typedef typename Graph::Node Node;
 
   359     typedef typename Graph::NodeIt NodeIt;
 
   365       NodeT() : first_out(-1) {}
 
   368     typedef typename ItemSetTraits<Graph, Node>::
 
   369     template Map<NodeT>::Type NodesImplBase;
 
   371     NodesImplBase* nodes;
 
   375       int prev_out, next_out;
 
   376       ArcT() : prev_out(-1), next_out(-1) {}
 
   379     std::vector<ArcT> arcs;
 
   386     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
 
   394       friend class ListEdgeSetBase;
 
   398       explicit Edge(int _id) { id = _id;}
 
   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;}
 
   409       friend class ListEdgeSetBase;
 
   411       Arc(int _id) : id(_id) {}
 
   414       operator Edge() const { return edgeFromId(id / 2); }
 
   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; }
 
   423     ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
 
   425     Edge addEdge(const Node& u, const Node& v) {
 
   428       if (first_free_arc == -1) {
 
   430         arcs.push_back(ArcT());
 
   431         arcs.push_back(ArcT());
 
   434         first_free_arc = arcs[n].next_out;
 
   438       arcs[n | 1].target = v;
 
   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;
 
   444       (*nodes)[v].first_out = n;
 
   445       arcs[n].prev_out = -1;
 
   447       if ((*nodes)[u].first_out != -1) {
 
   448         arcs[(*nodes)[u].first_out].prev_out = (n | 1);
 
   450       arcs[n | 1].next_out = (*nodes)[u].first_out;
 
   451       (*nodes)[u].first_out = (n | 1);
 
   452       arcs[n | 1].prev_out = -1;
 
   457     void erase(const Edge& arc) {
 
   460       if (arcs[n].next_out != -1) {
 
   461         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
 
   464       if (arcs[n].prev_out != -1) {
 
   465         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
 
   467         (*nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
 
   470       if (arcs[n | 1].next_out != -1) {
 
   471         arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
 
   474       if (arcs[n | 1].prev_out != -1) {
 
   475         arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
 
   477         (*nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
 
   480       arcs[n].next_out = first_free_arc;
 
   487       for (first(node); node != INVALID; next(node)) {
 
   488         (*nodes)[node].first_out = -1;
 
   495     void first(Node& node) const {
 
   499     void next(Node& node) const {
 
   503     void first(Arc& arc) const {
 
   506       while (node != INVALID && (*nodes)[node].first_out == -1) {
 
   509       arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
 
   512     void next(Arc& arc) const {
 
   513       if (arcs[arc.id].next_out != -1) {
 
   514         arc.id = arcs[arc.id].next_out;
 
   516         Node node = arcs[arc.id ^ 1].target;
 
   518         while(node != INVALID && (*nodes)[node].first_out == -1) {
 
   521         arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
 
   525     void first(Edge& edge) const {
 
   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;
 
   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;
 
   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;
 
   567     void firstOut(Arc& arc, const Node& node) const {
 
   568       arc.id = (*nodes)[node].first_out;
 
   571     void nextOut(Arc& arc) const {
 
   572       arc.id = arcs[arc.id].next_out;
 
   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;
 
   580     void nextIn(Arc& arc) const {
 
   581       arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
 
   582       if (arc.id == -2) arc.id = -1;
 
   585     void firstInc(Edge &arc, bool& dir, const Node& node) const {
 
   586       int de = (*nodes)[node].first_out;
 
   589         dir = ((de & 1) == 1);
 
   595     void nextInc(Edge &arc, bool& dir) const {
 
   596       int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
 
   599         dir = ((de & 1) == 1);
 
   606     static bool direction(Arc arc) {
 
   607       return (arc.id & 1) == 1;
 
   610     static Arc direct(Edge edge, bool dir) {
 
   611       return Arc(edge.id * 2 + (dir ? 1 : 0));
 
   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; }
 
   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);}
 
   622     int maxNodeId() const { return graph->maxNodeId(); };
 
   623     int maxEdgeId() const { return arcs.size() / 2 - 1; }
 
   624     int maxArcId() const { return arcs.size()-1; }
 
   626     Node source(Arc e) const { return arcs[e.id ^ 1].target; }
 
   627     Node target(Arc e) const { return arcs[e.id].target; }
 
   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; }
 
   632     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
 
   634     NodeNotifier& notifier(Node) const {
 
   635       return graph->notifier(Node());
 
   638     template <typename _Value>
 
   639     class NodeMap : public Graph::template NodeMap<_Value> {
 
   642       typedef typename _Graph::template NodeMap<_Value> Parent;
 
   644       explicit NodeMap(const ListEdgeSetBase<Graph>& arcset)
 
   645         : Parent(*arcset.graph) {}
 
   647       NodeMap(const ListEdgeSetBase<Graph>& arcset, const _Value& value)
 
   648         : Parent(*arcset.graph, value) {}
 
   650       NodeMap& operator=(const NodeMap& cmap) {
 
   651         return operator=<NodeMap>(cmap);
 
   654       template <typename CMap>
 
   655       NodeMap& operator=(const CMap& cmap) {
 
   656         Parent::operator=(cmap);
 
   663   /// \ingroup semi_adaptors
 
   665   /// \brief Graph using a node set of another digraph or graph and an
 
   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.
 
   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.
 
   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"
 
   687   /// This class is fully conform to the \ref concepts::Graph "Graph"
 
   689   template <typename _Graph>
 
   690   class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
 
   694     typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
 
   696     typedef typename Parent::Node Node;
 
   697     typedef typename Parent::Arc Arc;
 
   698     typedef typename Parent::Edge Edge;
 
   700     typedef _Graph Graph;
 
   703     typedef typename Parent::NodesImplBase NodesImplBase;
 
   705     void eraseNode(const Node& node) {
 
   707       Parent::firstOut(arc, node);
 
   708       while (arc != INVALID ) {
 
   710         Parent::firstOut(arc, node);
 
   719     class NodesImpl : public NodesImplBase {
 
   721       typedef NodesImplBase Parent;
 
   723       NodesImpl(const Graph& graph, ListEdgeSet& arcset)
 
   724         : Parent(graph), _arcset(arcset) {}
 
   726       virtual ~NodesImpl() {}
 
   730       virtual void erase(const Node& node) {
 
   731         _arcset.eraseNode(node);
 
   734       virtual void erase(const std::vector<Node>& nodes) {
 
   735         for (int i = 0; i < int(nodes.size()); ++i) {
 
   736           _arcset.eraseNode(nodes[i]);
 
   738         Parent::erase(nodes);
 
   740       virtual void clear() {
 
   741         _arcset.clearNodes();
 
   746       ListEdgeSet& _arcset;
 
   753     /// \brief Constructor of the EdgeSet.
 
   755     /// Constructor of the EdgeSet.
 
   756     ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
 
   757       Parent::initalize(graph, nodes);
 
   760     /// \brief Add a new edge to the graph.
 
   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);
 
   769     /// \brief Erase an edge from the graph.
 
   771     /// Erase the edge \c e from the graph.
 
   772     void erase(const Edge& e) {
 
   773       return Parent::erase(e);
 
   778   template <typename _Graph>
 
   779   class SmartArcSetBase {
 
   782     typedef _Graph Graph;
 
   783     typedef typename Graph::Node Node;
 
   784     typedef typename Graph::NodeIt NodeIt;
 
   789       int first_out, first_in;
 
   790       NodeT() : first_out(-1), first_in(-1) {}
 
   793     typedef typename ItemSetTraits<Graph, Node>::
 
   794     template Map<NodeT>::Type NodesImplBase;
 
   796     NodesImplBase* nodes;
 
   800       int next_out, next_in;
 
   804     std::vector<ArcT> arcs;
 
   808     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
 
   816       friend class SmartArcSetBase<Graph>;
 
   818       Arc(int _id) : id(_id) {}
 
   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; }
 
   830     Arc addArc(const Node& u, const Node& v) {
 
   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;
 
   844       for (first(node); node != INVALID; next(node)) {
 
   845         (*nodes)[node].first_in = -1;
 
   846         (*nodes)[node].first_out = -1;
 
   851     void first(Node& node) const {
 
   855     void next(Node& node) const {
 
   859     void first(Arc& arc) const {
 
   860       arc.id = arcs.size() - 1;
 
   863     void next(Arc& arc) const {
 
   867     void firstOut(Arc& arc, const Node& node) const {
 
   868       arc.id = (*nodes)[node].first_out;
 
   871     void nextOut(Arc& arc) const {
 
   872       arc.id = arcs[arc.id].next_out;
 
   875     void firstIn(Arc& arc, const Node& node) const {
 
   876       arc.id = (*nodes)[node].first_in;
 
   879     void nextIn(Arc& arc) const {
 
   880       arc.id = arcs[arc.id].next_in;
 
   883     int id(const Node& node) const { return graph->id(node); }
 
   884     int id(const Arc& arc) const { return arc.id; }
 
   886     Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
 
   887     Arc arcFromId(int ix) const { return Arc(ix); }
 
   889     int maxNodeId() const { return graph->maxNodeId(); };
 
   890     int maxArcId() const { return arcs.size() - 1; }
 
   892     Node source(const Arc& arc) const { return arcs[arc.id].source;}
 
   893     Node target(const Arc& arc) const { return arcs[arc.id].target;}
 
   895     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
 
   897     NodeNotifier& notifier(Node) const {
 
   898       return graph->notifier(Node());
 
   901     template <typename _Value>
 
   902     class NodeMap : public Graph::template NodeMap<_Value> {
 
   905       typedef typename _Graph::template NodeMap<_Value> Parent;
 
   907       explicit NodeMap(const SmartArcSetBase<Graph>& arcset)
 
   908         : Parent(*arcset.graph) { }
 
   910       NodeMap(const SmartArcSetBase<Graph>& arcset, const _Value& value)
 
   911         : Parent(*arcset.graph, value) { }
 
   913       NodeMap& operator=(const NodeMap& cmap) {
 
   914         return operator=<NodeMap>(cmap);
 
   917       template <typename CMap>
 
   918       NodeMap& operator=(const CMap& cmap) {
 
   919         Parent::operator=(cmap);
 
   927   /// \ingroup semi_adaptors
 
   929   /// \brief Digraph using a node set of another digraph or graph and
 
   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.
 
   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"
 
   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.
 
   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.
 
   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> > {
 
   962     typedef ArcSetExtender<SmartArcSetBase<_Graph> > Parent;
 
   964     typedef typename Parent::Node Node;
 
   965     typedef typename Parent::Arc Arc;
 
   967     typedef _Graph Graph;
 
   971     typedef typename Parent::NodesImplBase NodesImplBase;
 
   973     void eraseNode(const Node& node) {
 
   974       if (typename Parent::InArcIt(*this, node) == INVALID &&
 
   975           typename Parent::OutArcIt(*this, node) == INVALID) {
 
   978       throw typename NodesImplBase::Notifier::ImmediateDetach();
 
   985     class NodesImpl : public NodesImplBase {
 
   987       typedef NodesImplBase Parent;
 
   989       NodesImpl(const Graph& graph, SmartArcSet& arcset)
 
   990         : Parent(graph), _arcset(arcset) {}
 
   992       virtual ~NodesImpl() {}
 
   994       bool attached() const {
 
   995         return Parent::attached();
 
  1000       virtual void erase(const Node& node) {
 
  1002           _arcset.eraseNode(node);
 
  1003           Parent::erase(node);
 
  1004         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1009       virtual void erase(const std::vector<Node>& nodes) {
 
  1011           for (int i = 0; i < int(nodes.size()); ++i) {
 
  1012             _arcset.eraseNode(nodes[i]);
 
  1014           Parent::erase(nodes);
 
  1015         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1020       virtual void clear() {
 
  1021         _arcset.clearNodes();
 
  1026       SmartArcSet& _arcset;
 
  1033     /// \brief Constructor of the ArcSet.
 
  1035     /// Constructor of the ArcSet.
 
  1036     SmartArcSet(const Graph& graph) : nodes(graph, *this) {
 
  1037       Parent::initalize(graph, nodes);
 
  1040     /// \brief Add a new arc to the digraph.
 
  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);
 
  1049     /// \brief Validity check
 
  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();
 
  1061   template <typename _Graph>
 
  1062   class SmartEdgeSetBase {
 
  1065     typedef _Graph Graph;
 
  1066     typedef typename Graph::Node Node;
 
  1067     typedef typename Graph::NodeIt NodeIt;
 
  1073       NodeT() : first_out(-1) {}
 
  1076     typedef typename ItemSetTraits<Graph, Node>::
 
  1077     template Map<NodeT>::Type NodesImplBase;
 
  1079     NodesImplBase* nodes;
 
  1087     std::vector<ArcT> arcs;
 
  1091     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
 
  1099       friend class SmartEdgeSetBase;
 
  1103       explicit Edge(int _id) { id = _id;}
 
  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;}
 
  1114       friend class SmartEdgeSetBase;
 
  1116       Arc(int _id) : id(_id) {}
 
  1119       operator Edge() const { return edgeFromId(id / 2); }
 
  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; }
 
  1128     SmartEdgeSetBase() {}
 
  1130     Edge addEdge(const Node& u, const Node& v) {
 
  1131       int n = arcs.size();
 
  1132       arcs.push_back(ArcT());
 
  1133       arcs.push_back(ArcT());
 
  1136       arcs[n | 1].target = v;
 
  1138       arcs[n].next_out = (*nodes)[v].first_out;
 
  1139       (*nodes)[v].first_out = n;
 
  1141       arcs[n | 1].next_out = (*nodes)[u].first_out;
 
  1142       (*nodes)[u].first_out = (n | 1);
 
  1149       for (first(node); node != INVALID; next(node)) {
 
  1150         (*nodes)[node].first_out = -1;
 
  1155     void first(Node& node) const {
 
  1159     void next(Node& node) const {
 
  1163     void first(Arc& arc) const {
 
  1164       arc.id = arcs.size() - 1;
 
  1167     void next(Arc& arc) const {
 
  1171     void first(Edge& arc) const {
 
  1172       arc.id = arcs.size() / 2 - 1;
 
  1175     void next(Edge& arc) const {
 
  1179     void firstOut(Arc& arc, const Node& node) const {
 
  1180       arc.id = (*nodes)[node].first_out;
 
  1183     void nextOut(Arc& arc) const {
 
  1184       arc.id = arcs[arc.id].next_out;
 
  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;
 
  1192     void nextIn(Arc& arc) const {
 
  1193       arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
 
  1194       if (arc.id == -2) arc.id = -1;
 
  1197     void firstInc(Edge &arc, bool& dir, const Node& node) const {
 
  1198       int de = (*nodes)[node].first_out;
 
  1201         dir = ((de & 1) == 1);
 
  1207     void nextInc(Edge &arc, bool& dir) const {
 
  1208       int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
 
  1211         dir = ((de & 1) == 1);
 
  1218     static bool direction(Arc arc) {
 
  1219       return (arc.id & 1) == 1;
 
  1222     static Arc direct(Edge edge, bool dir) {
 
  1223       return Arc(edge.id * 2 + (dir ? 1 : 0));
 
  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; }
 
  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);}
 
  1234     int maxNodeId() const { return graph->maxNodeId(); };
 
  1235     int maxArcId() const { return arcs.size() - 1; }
 
  1236     int maxEdgeId() const { return arcs.size() / 2 - 1; }
 
  1238     Node source(Arc e) const { return arcs[e.id ^ 1].target; }
 
  1239     Node target(Arc e) const { return arcs[e.id].target; }
 
  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; }
 
  1244     typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
 
  1246     NodeNotifier& notifier(Node) const {
 
  1247       return graph->notifier(Node());
 
  1250     template <typename _Value>
 
  1251     class NodeMap : public Graph::template NodeMap<_Value> {
 
  1254       typedef typename _Graph::template NodeMap<_Value> Parent;
 
  1256       explicit NodeMap(const SmartEdgeSetBase<Graph>& arcset)
 
  1257         : Parent(*arcset.graph) { }
 
  1259       NodeMap(const SmartEdgeSetBase<Graph>& arcset, const _Value& value)
 
  1260         : Parent(*arcset.graph, value) { }
 
  1262       NodeMap& operator=(const NodeMap& cmap) {
 
  1263         return operator=<NodeMap>(cmap);
 
  1266       template <typename CMap>
 
  1267       NodeMap& operator=(const CMap& cmap) {
 
  1268         Parent::operator=(cmap);
 
  1275   /// \ingroup semi_adaptors
 
  1277   /// \brief Graph using a node set of another digraph or graph and an
 
  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.
 
  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"
 
  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.
 
  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.
 
  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> > {
 
  1310     typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
 
  1312     typedef typename Parent::Node Node;
 
  1313     typedef typename Parent::Arc Arc;
 
  1314     typedef typename Parent::Edge Edge;
 
  1316     typedef _Graph Graph;
 
  1320     typedef typename Parent::NodesImplBase NodesImplBase;
 
  1322     void eraseNode(const Node& node) {
 
  1323       if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
 
  1326       throw typename NodesImplBase::Notifier::ImmediateDetach();
 
  1333     class NodesImpl : public NodesImplBase {
 
  1335       typedef NodesImplBase Parent;
 
  1337       NodesImpl(const Graph& graph, SmartEdgeSet& arcset)
 
  1338         : Parent(graph), _arcset(arcset) {}
 
  1340       virtual ~NodesImpl() {}
 
  1342       bool attached() const {
 
  1343         return Parent::attached();
 
  1348       virtual void erase(const Node& node) {
 
  1350           _arcset.eraseNode(node);
 
  1351           Parent::erase(node);
 
  1352         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1357       virtual void erase(const std::vector<Node>& nodes) {
 
  1359           for (int i = 0; i < int(nodes.size()); ++i) {
 
  1360             _arcset.eraseNode(nodes[i]);
 
  1362           Parent::erase(nodes);
 
  1363         } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
 
  1368       virtual void clear() {
 
  1369         _arcset.clearNodes();
 
  1374       SmartEdgeSet& _arcset;
 
  1381     /// \brief Constructor of the EdgeSet.
 
  1383     /// Constructor of the EdgeSet.
 
  1384     SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
 
  1385       Parent::initalize(graph, nodes);
 
  1388     /// \brief Add a new edge to the graph.
 
  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);
 
  1397     /// \brief Validity check
 
  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();