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