lemon/smart_graph.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 629 7a28e215f715
child 782 853fcddcf282
child 825 a143f19f465b
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
     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-2009
     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_SMART_GRAPH_H
    20 #define LEMON_SMART_GRAPH_H
    21 
    22 ///\ingroup graphs
    23 ///\file
    24 ///\brief SmartDigraph and SmartGraph classes.
    25 
    26 #include <vector>
    27 
    28 #include <lemon/core.h>
    29 #include <lemon/error.h>
    30 #include <lemon/bits/graph_extender.h>
    31 
    32 namespace lemon {
    33 
    34   class SmartDigraph;
    35   ///Base of SmartDigraph
    36 
    37   ///Base of SmartDigraph
    38   ///
    39   class SmartDigraphBase {
    40   protected:
    41 
    42     struct NodeT
    43     {
    44       int first_in, first_out;
    45       NodeT() {}
    46     };
    47     struct ArcT
    48     {
    49       int target, source, next_in, next_out;
    50       ArcT() {}
    51     };
    52 
    53     std::vector<NodeT> nodes;
    54     std::vector<ArcT> arcs;
    55 
    56   public:
    57 
    58     typedef SmartDigraphBase Digraph;
    59 
    60     class Node;
    61     class Arc;
    62 
    63   public:
    64 
    65     SmartDigraphBase() : nodes(), arcs() { }
    66     SmartDigraphBase(const SmartDigraphBase &_g)
    67       : nodes(_g.nodes), arcs(_g.arcs) { }
    68 
    69     typedef True NodeNumTag;
    70     typedef True ArcNumTag;
    71 
    72     int nodeNum() const { return nodes.size(); }
    73     int arcNum() const { return arcs.size(); }
    74 
    75     int maxNodeId() const { return nodes.size()-1; }
    76     int maxArcId() const { return arcs.size()-1; }
    77 
    78     Node addNode() {
    79       int n = nodes.size();
    80       nodes.push_back(NodeT());
    81       nodes[n].first_in = -1;
    82       nodes[n].first_out = -1;
    83       return Node(n);
    84     }
    85 
    86     Arc addArc(Node u, Node v) {
    87       int n = arcs.size();
    88       arcs.push_back(ArcT());
    89       arcs[n].source = u._id;
    90       arcs[n].target = v._id;
    91       arcs[n].next_out = nodes[u._id].first_out;
    92       arcs[n].next_in = nodes[v._id].first_in;
    93       nodes[u._id].first_out = nodes[v._id].first_in = n;
    94 
    95       return Arc(n);
    96     }
    97 
    98     void clear() {
    99       arcs.clear();
   100       nodes.clear();
   101     }
   102 
   103     Node source(Arc a) const { return Node(arcs[a._id].source); }
   104     Node target(Arc a) const { return Node(arcs[a._id].target); }
   105 
   106     static int id(Node v) { return v._id; }
   107     static int id(Arc a) { return a._id; }
   108 
   109     static Node nodeFromId(int id) { return Node(id);}
   110     static Arc arcFromId(int id) { return Arc(id);}
   111 
   112     bool valid(Node n) const {
   113       return n._id >= 0 && n._id < static_cast<int>(nodes.size());
   114     }
   115     bool valid(Arc a) const {
   116       return a._id >= 0 && a._id < static_cast<int>(arcs.size());
   117     }
   118 
   119     class Node {
   120       friend class SmartDigraphBase;
   121       friend class SmartDigraph;
   122 
   123     protected:
   124       int _id;
   125       explicit Node(int id) : _id(id) {}
   126     public:
   127       Node() {}
   128       Node (Invalid) : _id(-1) {}
   129       bool operator==(const Node i) const {return _id == i._id;}
   130       bool operator!=(const Node i) const {return _id != i._id;}
   131       bool operator<(const Node i) const {return _id < i._id;}
   132     };
   133 
   134 
   135     class Arc {
   136       friend class SmartDigraphBase;
   137       friend class SmartDigraph;
   138 
   139     protected:
   140       int _id;
   141       explicit Arc(int id) : _id(id) {}
   142     public:
   143       Arc() { }
   144       Arc (Invalid) : _id(-1) {}
   145       bool operator==(const Arc i) const {return _id == i._id;}
   146       bool operator!=(const Arc i) const {return _id != i._id;}
   147       bool operator<(const Arc i) const {return _id < i._id;}
   148     };
   149 
   150     void first(Node& node) const {
   151       node._id = nodes.size() - 1;
   152     }
   153 
   154     static void next(Node& node) {
   155       --node._id;
   156     }
   157 
   158     void first(Arc& arc) const {
   159       arc._id = arcs.size() - 1;
   160     }
   161 
   162     static void next(Arc& arc) {
   163       --arc._id;
   164     }
   165 
   166     void firstOut(Arc& arc, const Node& node) const {
   167       arc._id = nodes[node._id].first_out;
   168     }
   169 
   170     void nextOut(Arc& arc) const {
   171       arc._id = arcs[arc._id].next_out;
   172     }
   173 
   174     void firstIn(Arc& arc, const Node& node) const {
   175       arc._id = nodes[node._id].first_in;
   176     }
   177 
   178     void nextIn(Arc& arc) const {
   179       arc._id = arcs[arc._id].next_in;
   180     }
   181 
   182   };
   183 
   184   typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
   185 
   186   ///\ingroup graphs
   187   ///
   188   ///\brief A smart directed graph class.
   189   ///
   190   ///This is a simple and fast digraph implementation.
   191   ///It is also quite memory efficient, but at the price
   192   ///that <b> it does support only limited (only stack-like)
   193   ///node and arc deletions</b>.
   194   ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
   195   ///
   196   ///\sa concepts::Digraph.
   197   class SmartDigraph : public ExtendedSmartDigraphBase {
   198     typedef ExtendedSmartDigraphBase Parent;
   199 
   200   private:
   201 
   202     ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
   203 
   204     ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
   205     ///
   206     SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
   207     ///\brief Assignment of SmartDigraph to another one is \e not allowed.
   208     ///Use DigraphCopy() instead.
   209 
   210     ///Assignment of SmartDigraph to another one is \e not allowed.
   211     ///Use DigraphCopy() instead.
   212     void operator=(const SmartDigraph &) {}
   213 
   214   public:
   215 
   216     /// Constructor
   217 
   218     /// Constructor.
   219     ///
   220     SmartDigraph() {};
   221 
   222     ///Add a new node to the digraph.
   223 
   224     /// Add a new node to the digraph.
   225     /// \return The new node.
   226     Node addNode() { return Parent::addNode(); }
   227 
   228     ///Add a new arc to the digraph.
   229 
   230     ///Add a new arc to the digraph with source node \c s
   231     ///and target node \c t.
   232     ///\return The new arc.
   233     Arc addArc(const Node& s, const Node& t) {
   234       return Parent::addArc(s, t);
   235     }
   236 
   237     /// \brief Using this it is possible to avoid the superfluous memory
   238     /// allocation.
   239 
   240     /// Using this it is possible to avoid the superfluous memory
   241     /// allocation: if you know that the digraph you want to build will
   242     /// be very large (e.g. it will contain millions of nodes and/or arcs)
   243     /// then it is worth reserving space for this amount before starting
   244     /// to build the digraph.
   245     /// \sa reserveArc
   246     void reserveNode(int n) { nodes.reserve(n); };
   247 
   248     /// \brief Using this it is possible to avoid the superfluous memory
   249     /// allocation.
   250 
   251     /// Using this it is possible to avoid the superfluous memory
   252     /// allocation: if you know that the digraph you want to build will
   253     /// be very large (e.g. it will contain millions of nodes and/or arcs)
   254     /// then it is worth reserving space for this amount before starting
   255     /// to build the digraph.
   256     /// \sa reserveNode
   257     void reserveArc(int m) { arcs.reserve(m); };
   258 
   259     /// \brief Node validity check
   260     ///
   261     /// This function gives back true if the given node is valid,
   262     /// ie. it is a real node of the graph.
   263     ///
   264     /// \warning A removed node (using Snapshot) could become valid again
   265     /// when new nodes are added to the graph.
   266     bool valid(Node n) const { return Parent::valid(n); }
   267 
   268     /// \brief Arc validity check
   269     ///
   270     /// This function gives back true if the given arc is valid,
   271     /// ie. it is a real arc of the graph.
   272     ///
   273     /// \warning A removed arc (using Snapshot) could become valid again
   274     /// when new arcs are added to the graph.
   275     bool valid(Arc a) const { return Parent::valid(a); }
   276 
   277     ///Clear the digraph.
   278 
   279     ///Erase all the nodes and arcs from the digraph.
   280     ///
   281     void clear() {
   282       Parent::clear();
   283     }
   284 
   285     ///Split a node.
   286 
   287     ///This function splits a node. First a new node is added to the digraph,
   288     ///then the source of each outgoing arc of \c n is moved to this new node.
   289     ///If \c connect is \c true (this is the default value), then a new arc
   290     ///from \c n to the newly created node is also added.
   291     ///\return The newly created node.
   292     ///
   293     ///\note The <tt>Arc</tt>s
   294     ///referencing a moved arc remain
   295     ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
   296     ///may be invalidated.
   297     ///\warning This functionality cannot be used together with the Snapshot
   298     ///feature.
   299     Node split(Node n, bool connect = true)
   300     {
   301       Node b = addNode();
   302       nodes[b._id].first_out=nodes[n._id].first_out;
   303       nodes[n._id].first_out=-1;
   304       for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
   305         arcs[i].source=b._id;
   306       }
   307       if(connect) addArc(n,b);
   308       return b;
   309     }
   310 
   311   public:
   312 
   313     class Snapshot;
   314 
   315   protected:
   316 
   317     void restoreSnapshot(const Snapshot &s)
   318     {
   319       while(s.arc_num<arcs.size()) {
   320         Arc arc = arcFromId(arcs.size()-1);
   321         Parent::notifier(Arc()).erase(arc);
   322         nodes[arcs.back().source].first_out=arcs.back().next_out;
   323         nodes[arcs.back().target].first_in=arcs.back().next_in;
   324         arcs.pop_back();
   325       }
   326       while(s.node_num<nodes.size()) {
   327         Node node = nodeFromId(nodes.size()-1);
   328         Parent::notifier(Node()).erase(node);
   329         nodes.pop_back();
   330       }
   331     }
   332 
   333   public:
   334 
   335     ///Class to make a snapshot of the digraph and to restrore to it later.
   336 
   337     ///Class to make a snapshot of the digraph and to restrore to it later.
   338     ///
   339     ///The newly added nodes and arcs can be removed using the
   340     ///restore() function.
   341     ///\note After you restore a state, you cannot restore
   342     ///a later state, in other word you cannot add again the arcs deleted
   343     ///by restore() using another one Snapshot instance.
   344     ///
   345     ///\warning If you do not use correctly the snapshot that can cause
   346     ///either broken program, invalid state of the digraph, valid but
   347     ///not the restored digraph or no change. Because the runtime performance
   348     ///the validity of the snapshot is not stored.
   349     class Snapshot
   350     {
   351       SmartDigraph *_graph;
   352     protected:
   353       friend class SmartDigraph;
   354       unsigned int node_num;
   355       unsigned int arc_num;
   356     public:
   357       ///Default constructor.
   358 
   359       ///Default constructor.
   360       ///To actually make a snapshot you must call save().
   361       ///
   362       Snapshot() : _graph(0) {}
   363       ///Constructor that immediately makes a snapshot
   364 
   365       ///This constructor immediately makes a snapshot of the digraph.
   366       ///\param graph The digraph we make a snapshot of.
   367       Snapshot(SmartDigraph &graph) : _graph(&graph) {
   368         node_num=_graph->nodes.size();
   369         arc_num=_graph->arcs.size();
   370       }
   371 
   372       ///Make a snapshot.
   373 
   374       ///Make a snapshot of the digraph.
   375       ///
   376       ///This function can be called more than once. In case of a repeated
   377       ///call, the previous snapshot gets lost.
   378       ///\param graph The digraph we make the snapshot of.
   379       void save(SmartDigraph &graph)
   380       {
   381         _graph=&graph;
   382         node_num=_graph->nodes.size();
   383         arc_num=_graph->arcs.size();
   384       }
   385 
   386       ///Undo the changes until a snapshot.
   387 
   388       ///Undo the changes until a snapshot created by save().
   389       ///
   390       ///\note After you restored a state, you cannot restore
   391       ///a later state, in other word you cannot add again the arcs deleted
   392       ///by restore().
   393       void restore()
   394       {
   395         _graph->restoreSnapshot(*this);
   396       }
   397     };
   398   };
   399 
   400 
   401   class SmartGraphBase {
   402 
   403   protected:
   404 
   405     struct NodeT {
   406       int first_out;
   407     };
   408 
   409     struct ArcT {
   410       int target;
   411       int next_out;
   412     };
   413 
   414     std::vector<NodeT> nodes;
   415     std::vector<ArcT> arcs;
   416 
   417     int first_free_arc;
   418 
   419   public:
   420 
   421     typedef SmartGraphBase Graph;
   422 
   423     class Node;
   424     class Arc;
   425     class Edge;
   426 
   427     class Node {
   428       friend class SmartGraphBase;
   429     protected:
   430 
   431       int _id;
   432       explicit Node(int id) { _id = id;}
   433 
   434     public:
   435       Node() {}
   436       Node (Invalid) { _id = -1; }
   437       bool operator==(const Node& node) const {return _id == node._id;}
   438       bool operator!=(const Node& node) const {return _id != node._id;}
   439       bool operator<(const Node& node) const {return _id < node._id;}
   440     };
   441 
   442     class Edge {
   443       friend class SmartGraphBase;
   444     protected:
   445 
   446       int _id;
   447       explicit Edge(int id) { _id = id;}
   448 
   449     public:
   450       Edge() {}
   451       Edge (Invalid) { _id = -1; }
   452       bool operator==(const Edge& arc) const {return _id == arc._id;}
   453       bool operator!=(const Edge& arc) const {return _id != arc._id;}
   454       bool operator<(const Edge& arc) const {return _id < arc._id;}
   455     };
   456 
   457     class Arc {
   458       friend class SmartGraphBase;
   459     protected:
   460 
   461       int _id;
   462       explicit Arc(int id) { _id = id;}
   463 
   464     public:
   465       operator Edge() const {
   466         return _id != -1 ? edgeFromId(_id / 2) : INVALID;
   467       }
   468 
   469       Arc() {}
   470       Arc (Invalid) { _id = -1; }
   471       bool operator==(const Arc& arc) const {return _id == arc._id;}
   472       bool operator!=(const Arc& arc) const {return _id != arc._id;}
   473       bool operator<(const Arc& arc) const {return _id < arc._id;}
   474     };
   475 
   476 
   477 
   478     SmartGraphBase()
   479       : nodes(), arcs() {}
   480 
   481     typedef True NodeNumTag;
   482     typedef True EdgeNumTag;
   483     typedef True ArcNumTag;
   484 
   485     int nodeNum() const { return nodes.size(); }
   486     int edgeNum() const { return arcs.size() / 2; }
   487     int arcNum() const { return arcs.size(); }
   488 
   489     int maxNodeId() const { return nodes.size()-1; }
   490     int maxEdgeId() const { return arcs.size() / 2 - 1; }
   491     int maxArcId() const { return arcs.size()-1; }
   492 
   493     Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
   494     Node target(Arc e) const { return Node(arcs[e._id].target); }
   495 
   496     Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
   497     Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
   498 
   499     static bool direction(Arc e) {
   500       return (e._id & 1) == 1;
   501     }
   502 
   503     static Arc direct(Edge e, bool d) {
   504       return Arc(e._id * 2 + (d ? 1 : 0));
   505     }
   506 
   507     void first(Node& node) const {
   508       node._id = nodes.size() - 1;
   509     }
   510 
   511     void next(Node& node) const {
   512       --node._id;
   513     }
   514 
   515     void first(Arc& arc) const {
   516       arc._id = arcs.size() - 1;
   517     }
   518 
   519     void next(Arc& arc) const {
   520       --arc._id;
   521     }
   522 
   523     void first(Edge& arc) const {
   524       arc._id = arcs.size() / 2 - 1;
   525     }
   526 
   527     void next(Edge& arc) const {
   528       --arc._id;
   529     }
   530 
   531     void firstOut(Arc &arc, const Node& v) const {
   532       arc._id = nodes[v._id].first_out;
   533     }
   534     void nextOut(Arc &arc) const {
   535       arc._id = arcs[arc._id].next_out;
   536     }
   537 
   538     void firstIn(Arc &arc, const Node& v) const {
   539       arc._id = ((nodes[v._id].first_out) ^ 1);
   540       if (arc._id == -2) arc._id = -1;
   541     }
   542     void nextIn(Arc &arc) const {
   543       arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
   544       if (arc._id == -2) arc._id = -1;
   545     }
   546 
   547     void firstInc(Edge &arc, bool& d, const Node& v) const {
   548       int de = nodes[v._id].first_out;
   549       if (de != -1) {
   550         arc._id = de / 2;
   551         d = ((de & 1) == 1);
   552       } else {
   553         arc._id = -1;
   554         d = true;
   555       }
   556     }
   557     void nextInc(Edge &arc, bool& d) const {
   558       int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
   559       if (de != -1) {
   560         arc._id = de / 2;
   561         d = ((de & 1) == 1);
   562       } else {
   563         arc._id = -1;
   564         d = true;
   565       }
   566     }
   567 
   568     static int id(Node v) { return v._id; }
   569     static int id(Arc e) { return e._id; }
   570     static int id(Edge e) { return e._id; }
   571 
   572     static Node nodeFromId(int id) { return Node(id);}
   573     static Arc arcFromId(int id) { return Arc(id);}
   574     static Edge edgeFromId(int id) { return Edge(id);}
   575 
   576     bool valid(Node n) const {
   577       return n._id >= 0 && n._id < static_cast<int>(nodes.size());
   578     }
   579     bool valid(Arc a) const {
   580       return a._id >= 0 && a._id < static_cast<int>(arcs.size());
   581     }
   582     bool valid(Edge e) const {
   583       return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
   584     }
   585 
   586     Node addNode() {
   587       int n = nodes.size();
   588       nodes.push_back(NodeT());
   589       nodes[n].first_out = -1;
   590 
   591       return Node(n);
   592     }
   593 
   594     Edge addEdge(Node u, Node v) {
   595       int n = arcs.size();
   596       arcs.push_back(ArcT());
   597       arcs.push_back(ArcT());
   598 
   599       arcs[n].target = u._id;
   600       arcs[n | 1].target = v._id;
   601 
   602       arcs[n].next_out = nodes[v._id].first_out;
   603       nodes[v._id].first_out = n;
   604 
   605       arcs[n | 1].next_out = nodes[u._id].first_out;
   606       nodes[u._id].first_out = (n | 1);
   607 
   608       return Edge(n / 2);
   609     }
   610 
   611     void clear() {
   612       arcs.clear();
   613       nodes.clear();
   614     }
   615 
   616   };
   617 
   618   typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
   619 
   620   /// \ingroup graphs
   621   ///
   622   /// \brief A smart undirected graph class.
   623   ///
   624   /// This is a simple and fast graph implementation.
   625   /// It is also quite memory efficient, but at the price
   626   /// that <b> it does support only limited (only stack-like)
   627   /// node and arc deletions</b>.
   628   /// It fully conforms to the \ref concepts::Graph "Graph concept".
   629   ///
   630   /// \sa concepts::Graph.
   631   class SmartGraph : public ExtendedSmartGraphBase {
   632     typedef ExtendedSmartGraphBase Parent;
   633 
   634   private:
   635 
   636     ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
   637 
   638     ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
   639     ///
   640     SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
   641 
   642     ///\brief Assignment of SmartGraph to another one is \e not allowed.
   643     ///Use GraphCopy() instead.
   644 
   645     ///Assignment of SmartGraph to another one is \e not allowed.
   646     ///Use GraphCopy() instead.
   647     void operator=(const SmartGraph &) {}
   648 
   649   public:
   650 
   651     /// Constructor
   652 
   653     /// Constructor.
   654     ///
   655     SmartGraph() {}
   656 
   657     ///Add a new node to the graph.
   658 
   659     /// Add a new node to the graph.
   660     /// \return The new node.
   661     Node addNode() { return Parent::addNode(); }
   662 
   663     ///Add a new edge to the graph.
   664 
   665     ///Add a new edge to the graph with node \c s
   666     ///and \c t.
   667     ///\return The new edge.
   668     Edge addEdge(const Node& s, const Node& t) {
   669       return Parent::addEdge(s, t);
   670     }
   671 
   672     /// \brief Node validity check
   673     ///
   674     /// This function gives back true if the given node is valid,
   675     /// ie. it is a real node of the graph.
   676     ///
   677     /// \warning A removed node (using Snapshot) could become valid again
   678     /// when new nodes are added to the graph.
   679     bool valid(Node n) const { return Parent::valid(n); }
   680 
   681     /// \brief Arc validity check
   682     ///
   683     /// This function gives back true if the given arc is valid,
   684     /// ie. it is a real arc of the graph.
   685     ///
   686     /// \warning A removed arc (using Snapshot) could become valid again
   687     /// when new edges are added to the graph.
   688     bool valid(Arc a) const { return Parent::valid(a); }
   689 
   690     /// \brief Edge validity check
   691     ///
   692     /// This function gives back true if the given edge is valid,
   693     /// ie. it is a real edge of the graph.
   694     ///
   695     /// \warning A removed edge (using Snapshot) could become valid again
   696     /// when new edges are added to the graph.
   697     bool valid(Edge e) const { return Parent::valid(e); }
   698 
   699     ///Clear the graph.
   700 
   701     ///Erase all the nodes and edges from the graph.
   702     ///
   703     void clear() {
   704       Parent::clear();
   705     }
   706 
   707   public:
   708 
   709     class Snapshot;
   710 
   711   protected:
   712 
   713     void saveSnapshot(Snapshot &s)
   714     {
   715       s._graph = this;
   716       s.node_num = nodes.size();
   717       s.arc_num = arcs.size();
   718     }
   719 
   720     void restoreSnapshot(const Snapshot &s)
   721     {
   722       while(s.arc_num<arcs.size()) {
   723         int n=arcs.size()-1;
   724         Edge arc=edgeFromId(n/2);
   725         Parent::notifier(Edge()).erase(arc);
   726         std::vector<Arc> dir;
   727         dir.push_back(arcFromId(n));
   728         dir.push_back(arcFromId(n-1));
   729         Parent::notifier(Arc()).erase(dir);
   730         nodes[arcs[n-1].target].first_out=arcs[n].next_out;
   731         nodes[arcs[n].target].first_out=arcs[n-1].next_out;
   732         arcs.pop_back();
   733         arcs.pop_back();
   734       }
   735       while(s.node_num<nodes.size()) {
   736         int n=nodes.size()-1;
   737         Node node = nodeFromId(n);
   738         Parent::notifier(Node()).erase(node);
   739         nodes.pop_back();
   740       }
   741     }
   742 
   743   public:
   744 
   745     ///Class to make a snapshot of the digraph and to restrore to it later.
   746 
   747     ///Class to make a snapshot of the digraph and to restrore to it later.
   748     ///
   749     ///The newly added nodes and arcs can be removed using the
   750     ///restore() function.
   751     ///
   752     ///\note After you restore a state, you cannot restore
   753     ///a later state, in other word you cannot add again the arcs deleted
   754     ///by restore() using another one Snapshot instance.
   755     ///
   756     ///\warning If you do not use correctly the snapshot that can cause
   757     ///either broken program, invalid state of the digraph, valid but
   758     ///not the restored digraph or no change. Because the runtime performance
   759     ///the validity of the snapshot is not stored.
   760     class Snapshot
   761     {
   762       SmartGraph *_graph;
   763     protected:
   764       friend class SmartGraph;
   765       unsigned int node_num;
   766       unsigned int arc_num;
   767     public:
   768       ///Default constructor.
   769 
   770       ///Default constructor.
   771       ///To actually make a snapshot you must call save().
   772       ///
   773       Snapshot() : _graph(0) {}
   774       ///Constructor that immediately makes a snapshot
   775 
   776       ///This constructor immediately makes a snapshot of the digraph.
   777       ///\param graph The digraph we make a snapshot of.
   778       Snapshot(SmartGraph &graph) {
   779         graph.saveSnapshot(*this);
   780       }
   781 
   782       ///Make a snapshot.
   783 
   784       ///Make a snapshot of the graph.
   785       ///
   786       ///This function can be called more than once. In case of a repeated
   787       ///call, the previous snapshot gets lost.
   788       ///\param graph The digraph we make the snapshot of.
   789       void save(SmartGraph &graph)
   790       {
   791         graph.saveSnapshot(*this);
   792       }
   793 
   794       ///Undo the changes until a snapshot.
   795 
   796       ///Undo the changes until a snapshot created by save().
   797       ///
   798       ///\note After you restored a state, you cannot restore
   799       ///a later state, in other word you cannot add again the arcs deleted
   800       ///by restore().
   801       void restore()
   802       {
   803         _graph->restoreSnapshot(*this);
   804       }
   805     };
   806   };
   807 
   808 } //namespace lemon
   809 
   810 
   811 #endif //LEMON_SMART_GRAPH_H