lemon/list_graph.h
author Akos Ladanyi <ladanyi@tmit.bme.hu>
Mon, 28 Jul 2008 12:39:58 +0100
changeset 236 da953e387d31
parent 220 a5d8c039f218
child 235 b46d2787e9c2
child 238 79643f6e8c52
permissions -rw-r--r--
Unify the spelling of LEMON (#103).
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_LIST_GRAPH_H
    20 #define LEMON_LIST_GRAPH_H
    21 
    22 ///\ingroup graphs
    23 ///\file
    24 ///\brief ListDigraph, ListGraph classes.
    25 
    26 #include <lemon/core.h>
    27 #include <lemon/error.h>
    28 #include <lemon/bits/graph_extender.h>
    29 
    30 #include <vector>
    31 #include <list>
    32 
    33 namespace lemon {
    34 
    35   class ListDigraphBase {
    36 
    37   protected:
    38     struct NodeT {
    39       int first_in, first_out;
    40       int prev, next;
    41     };
    42 
    43     struct ArcT {
    44       int target, source;
    45       int prev_in, prev_out;
    46       int next_in, next_out;
    47     };
    48 
    49     std::vector<NodeT> nodes;
    50 
    51     int first_node;
    52 
    53     int first_free_node;
    54 
    55     std::vector<ArcT> arcs;
    56 
    57     int first_free_arc;
    58 
    59   public:
    60 
    61     typedef ListDigraphBase Digraph;
    62 
    63     class Node {
    64       friend class ListDigraphBase;
    65     protected:
    66 
    67       int id;
    68       explicit Node(int pid) { id = pid;}
    69 
    70     public:
    71       Node() {}
    72       Node (Invalid) { id = -1; }
    73       bool operator==(const Node& node) const {return id == node.id;}
    74       bool operator!=(const Node& node) const {return id != node.id;}
    75       bool operator<(const Node& node) const {return id < node.id;}
    76     };
    77 
    78     class Arc {
    79       friend class ListDigraphBase;
    80     protected:
    81 
    82       int id;
    83       explicit Arc(int pid) { id = pid;}
    84 
    85     public:
    86       Arc() {}
    87       Arc (Invalid) { id = -1; }
    88       bool operator==(const Arc& arc) const {return id == arc.id;}
    89       bool operator!=(const Arc& arc) const {return id != arc.id;}
    90       bool operator<(const Arc& arc) const {return id < arc.id;}
    91     };
    92 
    93 
    94 
    95     ListDigraphBase()
    96       : nodes(), first_node(-1),
    97         first_free_node(-1), arcs(), first_free_arc(-1) {}
    98 
    99 
   100     int maxNodeId() const { return nodes.size()-1; }
   101     int maxArcId() const { return arcs.size()-1; }
   102 
   103     Node source(Arc e) const { return Node(arcs[e.id].source); }
   104     Node target(Arc e) const { return Node(arcs[e.id].target); }
   105 
   106 
   107     void first(Node& node) const {
   108       node.id = first_node;
   109     }
   110 
   111     void next(Node& node) const {
   112       node.id = nodes[node.id].next;
   113     }
   114 
   115 
   116     void first(Arc& arc) const {
   117       int n;
   118       for(n = first_node;
   119           n!=-1 && nodes[n].first_in == -1;
   120           n = nodes[n].next) {}
   121       arc.id = (n == -1) ? -1 : nodes[n].first_in;
   122     }
   123 
   124     void next(Arc& arc) const {
   125       if (arcs[arc.id].next_in != -1) {
   126         arc.id = arcs[arc.id].next_in;
   127       } else {
   128         int n;
   129         for(n = nodes[arcs[arc.id].target].next;
   130             n!=-1 && nodes[n].first_in == -1;
   131             n = nodes[n].next) {}
   132         arc.id = (n == -1) ? -1 : nodes[n].first_in;
   133       }
   134     }
   135 
   136     void firstOut(Arc &e, const Node& v) const {
   137       e.id = nodes[v.id].first_out;
   138     }
   139     void nextOut(Arc &e) const {
   140       e.id=arcs[e.id].next_out;
   141     }
   142 
   143     void firstIn(Arc &e, const Node& v) const {
   144       e.id = nodes[v.id].first_in;
   145     }
   146     void nextIn(Arc &e) const {
   147       e.id=arcs[e.id].next_in;
   148     }
   149 
   150 
   151     static int id(Node v) { return v.id; }
   152     static int id(Arc e) { return e.id; }
   153 
   154     static Node nodeFromId(int id) { return Node(id);}
   155     static Arc arcFromId(int id) { return Arc(id);}
   156 
   157     bool valid(Node n) const {
   158       return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
   159         nodes[n.id].prev != -2;
   160     }
   161 
   162     bool valid(Arc a) const {
   163       return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
   164         arcs[a.id].prev_in != -2;
   165     }
   166 
   167     Node addNode() {
   168       int n;
   169 
   170       if(first_free_node==-1) {
   171         n = nodes.size();
   172         nodes.push_back(NodeT());
   173       } else {
   174         n = first_free_node;
   175         first_free_node = nodes[n].next;
   176       }
   177 
   178       nodes[n].next = first_node;
   179       if(first_node != -1) nodes[first_node].prev = n;
   180       first_node = n;
   181       nodes[n].prev = -1;
   182 
   183       nodes[n].first_in = nodes[n].first_out = -1;
   184 
   185       return Node(n);
   186     }
   187 
   188     Arc addArc(Node u, Node v) {
   189       int n;
   190 
   191       if (first_free_arc == -1) {
   192         n = arcs.size();
   193         arcs.push_back(ArcT());
   194       } else {
   195         n = first_free_arc;
   196         first_free_arc = arcs[n].next_in;
   197       }
   198 
   199       arcs[n].source = u.id;
   200       arcs[n].target = v.id;
   201 
   202       arcs[n].next_out = nodes[u.id].first_out;
   203       if(nodes[u.id].first_out != -1) {
   204         arcs[nodes[u.id].first_out].prev_out = n;
   205       }
   206 
   207       arcs[n].next_in = nodes[v.id].first_in;
   208       if(nodes[v.id].first_in != -1) {
   209         arcs[nodes[v.id].first_in].prev_in = n;
   210       }
   211 
   212       arcs[n].prev_in = arcs[n].prev_out = -1;
   213 
   214       nodes[u.id].first_out = nodes[v.id].first_in = n;
   215 
   216       return Arc(n);
   217     }
   218 
   219     void erase(const Node& node) {
   220       int n = node.id;
   221 
   222       if(nodes[n].next != -1) {
   223         nodes[nodes[n].next].prev = nodes[n].prev;
   224       }
   225 
   226       if(nodes[n].prev != -1) {
   227         nodes[nodes[n].prev].next = nodes[n].next;
   228       } else {
   229         first_node = nodes[n].next;
   230       }
   231 
   232       nodes[n].next = first_free_node;
   233       first_free_node = n;
   234       nodes[n].prev = -2;
   235 
   236     }
   237 
   238     void erase(const Arc& arc) {
   239       int n = arc.id;
   240 
   241       if(arcs[n].next_in!=-1) {
   242         arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
   243       }
   244 
   245       if(arcs[n].prev_in!=-1) {
   246         arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
   247       } else {
   248         nodes[arcs[n].target].first_in = arcs[n].next_in;
   249       }
   250 
   251 
   252       if(arcs[n].next_out!=-1) {
   253         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
   254       }
   255 
   256       if(arcs[n].prev_out!=-1) {
   257         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
   258       } else {
   259         nodes[arcs[n].source].first_out = arcs[n].next_out;
   260       }
   261 
   262       arcs[n].next_in = first_free_arc;
   263       first_free_arc = n;
   264       arcs[n].prev_in = -2;
   265     }
   266 
   267     void clear() {
   268       arcs.clear();
   269       nodes.clear();
   270       first_node = first_free_node = first_free_arc = -1;
   271     }
   272 
   273   protected:
   274     void changeTarget(Arc e, Node n)
   275     {
   276       if(arcs[e.id].next_in != -1)
   277         arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
   278       if(arcs[e.id].prev_in != -1)
   279         arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
   280       else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
   281       if (nodes[n.id].first_in != -1) {
   282         arcs[nodes[n.id].first_in].prev_in = e.id;
   283       }
   284       arcs[e.id].target = n.id;
   285       arcs[e.id].prev_in = -1;
   286       arcs[e.id].next_in = nodes[n.id].first_in;
   287       nodes[n.id].first_in = e.id;
   288     }
   289     void changeSource(Arc e, Node n)
   290     {
   291       if(arcs[e.id].next_out != -1)
   292         arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
   293       if(arcs[e.id].prev_out != -1)
   294         arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
   295       else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
   296       if (nodes[n.id].first_out != -1) {
   297         arcs[nodes[n.id].first_out].prev_out = e.id;
   298       }
   299       arcs[e.id].source = n.id;
   300       arcs[e.id].prev_out = -1;
   301       arcs[e.id].next_out = nodes[n.id].first_out;
   302       nodes[n.id].first_out = e.id;
   303     }
   304 
   305   };
   306 
   307   typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
   308 
   309   /// \addtogroup graphs
   310   /// @{
   311 
   312   ///A general directed graph structure.
   313 
   314   ///\ref ListDigraph is a simple and fast <em>directed graph</em>
   315   ///implementation based on static linked lists that are stored in
   316   ///\c std::vector structures.
   317   ///
   318   ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
   319   ///also provides several useful additional functionalities.
   320   ///Most of the member functions and nested classes are documented
   321   ///only in the concept class.
   322   ///
   323   ///An important extra feature of this digraph implementation is that
   324   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
   325   ///
   326   ///\sa concepts::Digraph
   327 
   328   class ListDigraph : public ExtendedListDigraphBase {
   329   private:
   330     ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
   331 
   332     ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
   333     ///
   334     ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
   335     ///\brief Assignment of ListDigraph to another one is \e not allowed.
   336     ///Use copyDigraph() instead.
   337 
   338     ///Assignment of ListDigraph to another one is \e not allowed.
   339     ///Use copyDigraph() instead.
   340     void operator=(const ListDigraph &) {}
   341   public:
   342 
   343     typedef ExtendedListDigraphBase Parent;
   344 
   345     /// Constructor
   346 
   347     /// Constructor.
   348     ///
   349     ListDigraph() {}
   350 
   351     ///Add a new node to the digraph.
   352 
   353     ///Add a new node to the digraph.
   354     ///\return the new node.
   355     Node addNode() { return Parent::addNode(); }
   356 
   357     ///Add a new arc to the digraph.
   358 
   359     ///Add a new arc to the digraph with source node \c s
   360     ///and target node \c t.
   361     ///\return the new arc.
   362     Arc addArc(const Node& s, const Node& t) {
   363       return Parent::addArc(s, t);
   364     }
   365 
   366     ///\brief Erase a node from the digraph.
   367     ///
   368     ///Erase a node from the digraph.
   369     ///
   370     void erase(const Node& n) { Parent::erase(n); }
   371 
   372     ///\brief Erase an arc from the digraph.
   373     ///
   374     ///Erase an arc from the digraph.
   375     ///
   376     void erase(const Arc& a) { Parent::erase(a); }
   377 
   378     /// Node validity check
   379 
   380     /// This function gives back true if the given node is valid,
   381     /// ie. it is a real node of the graph.
   382     ///
   383     /// \warning A Node pointing to a removed item
   384     /// could become valid again later if new nodes are
   385     /// added to the graph.
   386     bool valid(Node n) const { return Parent::valid(n); }
   387 
   388     /// Arc validity check
   389 
   390     /// This function gives back true if the given arc is valid,
   391     /// ie. it is a real arc of the graph.
   392     ///
   393     /// \warning An Arc pointing to a removed item
   394     /// could become valid again later if new nodes are
   395     /// added to the graph.
   396     bool valid(Arc a) const { return Parent::valid(a); }
   397 
   398     /// Change the target of \c e to \c n
   399 
   400     /// Change the target of \c e to \c n
   401     ///
   402     ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
   403     ///the changed arc remain valid. However <tt>InArcIt</tt>s are
   404     ///invalidated.
   405     ///
   406     ///\warning This functionality cannot be used together with the Snapshot
   407     ///feature.
   408     void changeTarget(Arc e, Node n) {
   409       Parent::changeTarget(e,n);
   410     }
   411     /// Change the source of \c e to \c n
   412 
   413     /// Change the source of \c e to \c n
   414     ///
   415     ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
   416     ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
   417     ///invalidated.
   418     ///
   419     ///\warning This functionality cannot be used together with the Snapshot
   420     ///feature.
   421     void changeSource(Arc e, Node n) {
   422       Parent::changeSource(e,n);
   423     }
   424 
   425     /// Invert the direction of an arc.
   426 
   427     ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
   428     ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
   429     ///invalidated.
   430     ///
   431     ///\warning This functionality cannot be used together with the Snapshot
   432     ///feature.
   433     void reverseArc(Arc e) {
   434       Node t=target(e);
   435       changeTarget(e,source(e));
   436       changeSource(e,t);
   437     }
   438 
   439     /// Reserve memory for nodes.
   440 
   441     /// Using this function it is possible to avoid the superfluous memory
   442     /// allocation: if you know that the digraph you want to build will
   443     /// be very large (e.g. it will contain millions of nodes and/or arcs)
   444     /// then it is worth reserving space for this amount before starting
   445     /// to build the digraph.
   446     /// \sa reserveArc
   447     void reserveNode(int n) { nodes.reserve(n); };
   448 
   449     /// Reserve memory for arcs.
   450 
   451     /// Using this function it is possible to avoid the superfluous memory
   452     /// allocation: if you know that the digraph you want to build will
   453     /// be very large (e.g. it will contain millions of nodes and/or arcs)
   454     /// then it is worth reserving space for this amount before starting
   455     /// to build the digraph.
   456     /// \sa reserveNode
   457     void reserveArc(int m) { arcs.reserve(m); };
   458 
   459     ///Contract two nodes.
   460 
   461     ///This function contracts two nodes.
   462     ///Node \p b will be removed but instead of deleting
   463     ///incident arcs, they will be joined to \p a.
   464     ///The last parameter \p r controls whether to remove loops. \c true
   465     ///means that loops will be removed.
   466     ///
   467     ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
   468     ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
   469     ///may be invalidated.
   470     ///
   471     ///\warning This functionality cannot be used together with the Snapshot
   472     ///feature.
   473     void contract(Node a, Node b, bool r = true)
   474     {
   475       for(OutArcIt e(*this,b);e!=INVALID;) {
   476         OutArcIt f=e;
   477         ++f;
   478         if(r && target(e)==a) erase(e);
   479         else changeSource(e,a);
   480         e=f;
   481       }
   482       for(InArcIt e(*this,b);e!=INVALID;) {
   483         InArcIt f=e;
   484         ++f;
   485         if(r && source(e)==a) erase(e);
   486         else changeTarget(e,a);
   487         e=f;
   488       }
   489       erase(b);
   490     }
   491 
   492     ///Split a node.
   493 
   494     ///This function splits a node. First a new node is added to the digraph,
   495     ///then the source of each outgoing arc of \c n is moved to this new node.
   496     ///If \c connect is \c true (this is the default value), then a new arc
   497     ///from \c n to the newly created node is also added.
   498     ///\return The newly created node.
   499     ///
   500     ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
   501     ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
   502     ///be invalidated.
   503     ///
   504     ///\warning This functionality cannot be used together with the
   505     ///Snapshot feature.
   506     ///
   507     ///\todo It could be implemented in a bit faster way.
   508     Node split(Node n, bool connect = true) {
   509       Node b = addNode();
   510       for(OutArcIt e(*this,n);e!=INVALID;) {
   511         OutArcIt f=e;
   512         ++f;
   513         changeSource(e,b);
   514         e=f;
   515       }
   516       if (connect) addArc(n,b);
   517       return b;
   518     }
   519 
   520     ///Split an arc.
   521 
   522     ///This function splits an arc. First a new node \c b is added to
   523     ///the digraph, then the original arc is re-targeted to \c
   524     ///b. Finally an arc from \c b to the original target is added.
   525     ///
   526     ///\return The newly created node.
   527     ///
   528     ///\warning This functionality cannot be used together with the
   529     ///Snapshot feature.
   530     Node split(Arc e) {
   531       Node b = addNode();
   532       addArc(b,target(e));
   533       changeTarget(e,b);
   534       return b;
   535     }
   536 
   537     /// \brief Class to make a snapshot of the digraph and restore
   538     /// it later.
   539     ///
   540     /// Class to make a snapshot of the digraph and restore it later.
   541     ///
   542     /// The newly added nodes and arcs can be removed using the
   543     /// restore() function.
   544     ///
   545     /// \warning Arc and node deletions and other modifications (e.g.
   546     /// contracting, splitting, reversing arcs or nodes) cannot be
   547     /// restored. These events invalidate the snapshot.
   548     class Snapshot {
   549     protected:
   550 
   551       typedef Parent::NodeNotifier NodeNotifier;
   552 
   553       class NodeObserverProxy : public NodeNotifier::ObserverBase {
   554       public:
   555 
   556         NodeObserverProxy(Snapshot& _snapshot)
   557           : snapshot(_snapshot) {}
   558 
   559         using NodeNotifier::ObserverBase::attach;
   560         using NodeNotifier::ObserverBase::detach;
   561         using NodeNotifier::ObserverBase::attached;
   562 
   563       protected:
   564 
   565         virtual void add(const Node& node) {
   566           snapshot.addNode(node);
   567         }
   568         virtual void add(const std::vector<Node>& nodes) {
   569           for (int i = nodes.size() - 1; i >= 0; ++i) {
   570             snapshot.addNode(nodes[i]);
   571           }
   572         }
   573         virtual void erase(const Node& node) {
   574           snapshot.eraseNode(node);
   575         }
   576         virtual void erase(const std::vector<Node>& nodes) {
   577           for (int i = 0; i < int(nodes.size()); ++i) {
   578             snapshot.eraseNode(nodes[i]);
   579           }
   580         }
   581         virtual void build() {
   582           Node node;
   583           std::vector<Node> nodes;
   584           for (notifier()->first(node); node != INVALID;
   585                notifier()->next(node)) {
   586             nodes.push_back(node);
   587           }
   588           for (int i = nodes.size() - 1; i >= 0; --i) {
   589             snapshot.addNode(nodes[i]);
   590           }
   591         }
   592         virtual void clear() {
   593           Node node;
   594           for (notifier()->first(node); node != INVALID;
   595                notifier()->next(node)) {
   596             snapshot.eraseNode(node);
   597           }
   598         }
   599 
   600         Snapshot& snapshot;
   601       };
   602 
   603       class ArcObserverProxy : public ArcNotifier::ObserverBase {
   604       public:
   605 
   606         ArcObserverProxy(Snapshot& _snapshot)
   607           : snapshot(_snapshot) {}
   608 
   609         using ArcNotifier::ObserverBase::attach;
   610         using ArcNotifier::ObserverBase::detach;
   611         using ArcNotifier::ObserverBase::attached;
   612 
   613       protected:
   614 
   615         virtual void add(const Arc& arc) {
   616           snapshot.addArc(arc);
   617         }
   618         virtual void add(const std::vector<Arc>& arcs) {
   619           for (int i = arcs.size() - 1; i >= 0; ++i) {
   620             snapshot.addArc(arcs[i]);
   621           }
   622         }
   623         virtual void erase(const Arc& arc) {
   624           snapshot.eraseArc(arc);
   625         }
   626         virtual void erase(const std::vector<Arc>& arcs) {
   627           for (int i = 0; i < int(arcs.size()); ++i) {
   628             snapshot.eraseArc(arcs[i]);
   629           }
   630         }
   631         virtual void build() {
   632           Arc arc;
   633           std::vector<Arc> arcs;
   634           for (notifier()->first(arc); arc != INVALID;
   635                notifier()->next(arc)) {
   636             arcs.push_back(arc);
   637           }
   638           for (int i = arcs.size() - 1; i >= 0; --i) {
   639             snapshot.addArc(arcs[i]);
   640           }
   641         }
   642         virtual void clear() {
   643           Arc arc;
   644           for (notifier()->first(arc); arc != INVALID;
   645                notifier()->next(arc)) {
   646             snapshot.eraseArc(arc);
   647           }
   648         }
   649 
   650         Snapshot& snapshot;
   651       };
   652 
   653       ListDigraph *digraph;
   654 
   655       NodeObserverProxy node_observer_proxy;
   656       ArcObserverProxy arc_observer_proxy;
   657 
   658       std::list<Node> added_nodes;
   659       std::list<Arc> added_arcs;
   660 
   661 
   662       void addNode(const Node& node) {
   663         added_nodes.push_front(node);
   664       }
   665       void eraseNode(const Node& node) {
   666         std::list<Node>::iterator it =
   667           std::find(added_nodes.begin(), added_nodes.end(), node);
   668         if (it == added_nodes.end()) {
   669           clear();
   670           arc_observer_proxy.detach();
   671           throw NodeNotifier::ImmediateDetach();
   672         } else {
   673           added_nodes.erase(it);
   674         }
   675       }
   676 
   677       void addArc(const Arc& arc) {
   678         added_arcs.push_front(arc);
   679       }
   680       void eraseArc(const Arc& arc) {
   681         std::list<Arc>::iterator it =
   682           std::find(added_arcs.begin(), added_arcs.end(), arc);
   683         if (it == added_arcs.end()) {
   684           clear();
   685           node_observer_proxy.detach();
   686           throw ArcNotifier::ImmediateDetach();
   687         } else {
   688           added_arcs.erase(it);
   689         }
   690       }
   691 
   692       void attach(ListDigraph &_digraph) {
   693         digraph = &_digraph;
   694         node_observer_proxy.attach(digraph->notifier(Node()));
   695         arc_observer_proxy.attach(digraph->notifier(Arc()));
   696       }
   697 
   698       void detach() {
   699         node_observer_proxy.detach();
   700         arc_observer_proxy.detach();
   701       }
   702 
   703       bool attached() const {
   704         return node_observer_proxy.attached();
   705       }
   706 
   707       void clear() {
   708         added_nodes.clear();
   709         added_arcs.clear();
   710       }
   711 
   712     public:
   713 
   714       /// \brief Default constructor.
   715       ///
   716       /// Default constructor.
   717       /// To actually make a snapshot you must call save().
   718       Snapshot()
   719         : digraph(0), node_observer_proxy(*this),
   720           arc_observer_proxy(*this) {}
   721 
   722       /// \brief Constructor that immediately makes a snapshot.
   723       ///
   724       /// This constructor immediately makes a snapshot of the digraph.
   725       /// \param _digraph The digraph we make a snapshot of.
   726       Snapshot(ListDigraph &_digraph)
   727         : node_observer_proxy(*this),
   728           arc_observer_proxy(*this) {
   729         attach(_digraph);
   730       }
   731 
   732       /// \brief Make a snapshot.
   733       ///
   734       /// Make a snapshot of the digraph.
   735       ///
   736       /// This function can be called more than once. In case of a repeated
   737       /// call, the previous snapshot gets lost.
   738       /// \param _digraph The digraph we make the snapshot of.
   739       void save(ListDigraph &_digraph) {
   740         if (attached()) {
   741           detach();
   742           clear();
   743         }
   744         attach(_digraph);
   745       }
   746 
   747       /// \brief Undo the changes until the last snapshot.
   748       //
   749       /// Undo the changes until the last snapshot created by save().
   750       void restore() {
   751         detach();
   752         for(std::list<Arc>::iterator it = added_arcs.begin();
   753             it != added_arcs.end(); ++it) {
   754           digraph->erase(*it);
   755         }
   756         for(std::list<Node>::iterator it = added_nodes.begin();
   757             it != added_nodes.end(); ++it) {
   758           digraph->erase(*it);
   759         }
   760         clear();
   761       }
   762 
   763       /// \brief Gives back true when the snapshot is valid.
   764       ///
   765       /// Gives back true when the snapshot is valid.
   766       bool valid() const {
   767         return attached();
   768       }
   769     };
   770 
   771   };
   772 
   773   ///@}
   774 
   775   class ListGraphBase {
   776 
   777   protected:
   778 
   779     struct NodeT {
   780       int first_out;
   781       int prev, next;
   782     };
   783 
   784     struct ArcT {
   785       int target;
   786       int prev_out, next_out;
   787     };
   788 
   789     std::vector<NodeT> nodes;
   790 
   791     int first_node;
   792 
   793     int first_free_node;
   794 
   795     std::vector<ArcT> arcs;
   796 
   797     int first_free_arc;
   798 
   799   public:
   800 
   801     typedef ListGraphBase Digraph;
   802 
   803     class Node;
   804     class Arc;
   805     class Edge;
   806 
   807     class Node {
   808       friend class ListGraphBase;
   809     protected:
   810 
   811       int id;
   812       explicit Node(int pid) { id = pid;}
   813 
   814     public:
   815       Node() {}
   816       Node (Invalid) { id = -1; }
   817       bool operator==(const Node& node) const {return id == node.id;}
   818       bool operator!=(const Node& node) const {return id != node.id;}
   819       bool operator<(const Node& node) const {return id < node.id;}
   820     };
   821 
   822     class Edge {
   823       friend class ListGraphBase;
   824     protected:
   825 
   826       int id;
   827       explicit Edge(int pid) { id = pid;}
   828 
   829     public:
   830       Edge() {}
   831       Edge (Invalid) { id = -1; }
   832       bool operator==(const Edge& edge) const {return id == edge.id;}
   833       bool operator!=(const Edge& edge) const {return id != edge.id;}
   834       bool operator<(const Edge& edge) const {return id < edge.id;}
   835     };
   836 
   837     class Arc {
   838       friend class ListGraphBase;
   839     protected:
   840 
   841       int id;
   842       explicit Arc(int pid) { id = pid;}
   843 
   844     public:
   845       operator Edge() const { return edgeFromId(id / 2); }
   846 
   847       Arc() {}
   848       Arc (Invalid) { id = -1; }
   849       bool operator==(const Arc& arc) const {return id == arc.id;}
   850       bool operator!=(const Arc& arc) const {return id != arc.id;}
   851       bool operator<(const Arc& arc) const {return id < arc.id;}
   852     };
   853 
   854 
   855 
   856     ListGraphBase()
   857       : nodes(), first_node(-1),
   858         first_free_node(-1), arcs(), first_free_arc(-1) {}
   859 
   860 
   861     int maxNodeId() const { return nodes.size()-1; }
   862     int maxEdgeId() const { return arcs.size() / 2 - 1; }
   863     int maxArcId() const { return arcs.size()-1; }
   864 
   865     Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
   866     Node target(Arc e) const { return Node(arcs[e.id].target); }
   867 
   868     Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
   869     Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
   870 
   871     static bool direction(Arc e) {
   872       return (e.id & 1) == 1;
   873     }
   874 
   875     static Arc direct(Edge e, bool d) {
   876       return Arc(e.id * 2 + (d ? 1 : 0));
   877     }
   878 
   879     void first(Node& node) const {
   880       node.id = first_node;
   881     }
   882 
   883     void next(Node& node) const {
   884       node.id = nodes[node.id].next;
   885     }
   886 
   887     void first(Arc& e) const {
   888       int n = first_node;
   889       while (n != -1 && nodes[n].first_out == -1) {
   890         n = nodes[n].next;
   891       }
   892       e.id = (n == -1) ? -1 : nodes[n].first_out;
   893     }
   894 
   895     void next(Arc& e) const {
   896       if (arcs[e.id].next_out != -1) {
   897         e.id = arcs[e.id].next_out;
   898       } else {
   899         int n = nodes[arcs[e.id ^ 1].target].next;
   900         while(n != -1 && nodes[n].first_out == -1) {
   901           n = nodes[n].next;
   902         }
   903         e.id = (n == -1) ? -1 : nodes[n].first_out;
   904       }
   905     }
   906 
   907     void first(Edge& e) const {
   908       int n = first_node;
   909       while (n != -1) {
   910         e.id = nodes[n].first_out;
   911         while ((e.id & 1) != 1) {
   912           e.id = arcs[e.id].next_out;
   913         }
   914         if (e.id != -1) {
   915           e.id /= 2;
   916           return;
   917         }
   918         n = nodes[n].next;
   919       }
   920       e.id = -1;
   921     }
   922 
   923     void next(Edge& e) const {
   924       int n = arcs[e.id * 2].target;
   925       e.id = arcs[(e.id * 2) | 1].next_out;
   926       while ((e.id & 1) != 1) {
   927         e.id = arcs[e.id].next_out;
   928       }
   929       if (e.id != -1) {
   930         e.id /= 2;
   931         return;
   932       }
   933       n = nodes[n].next;
   934       while (n != -1) {
   935         e.id = nodes[n].first_out;
   936         while ((e.id & 1) != 1) {
   937           e.id = arcs[e.id].next_out;
   938         }
   939         if (e.id != -1) {
   940           e.id /= 2;
   941           return;
   942         }
   943         n = nodes[n].next;
   944       }
   945       e.id = -1;
   946     }
   947 
   948     void firstOut(Arc &e, const Node& v) const {
   949       e.id = nodes[v.id].first_out;
   950     }
   951     void nextOut(Arc &e) const {
   952       e.id = arcs[e.id].next_out;
   953     }
   954 
   955     void firstIn(Arc &e, const Node& v) const {
   956       e.id = ((nodes[v.id].first_out) ^ 1);
   957       if (e.id == -2) e.id = -1;
   958     }
   959     void nextIn(Arc &e) const {
   960       e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
   961       if (e.id == -2) e.id = -1;
   962     }
   963 
   964     void firstInc(Edge &e, bool& d, const Node& v) const {
   965       int a = nodes[v.id].first_out;
   966       if (a != -1 ) {
   967         e.id = a / 2;
   968         d = ((a & 1) == 1);
   969       } else {
   970         e.id = -1;
   971         d = true;
   972       }
   973     }
   974     void nextInc(Edge &e, bool& d) const {
   975       int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
   976       if (a != -1 ) {
   977         e.id = a / 2;
   978         d = ((a & 1) == 1);
   979       } else {
   980         e.id = -1;
   981         d = true;
   982       }
   983     }
   984 
   985     static int id(Node v) { return v.id; }
   986     static int id(Arc e) { return e.id; }
   987     static int id(Edge e) { return e.id; }
   988 
   989     static Node nodeFromId(int id) { return Node(id);}
   990     static Arc arcFromId(int id) { return Arc(id);}
   991     static Edge edgeFromId(int id) { return Edge(id);}
   992 
   993     bool valid(Node n) const {
   994       return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
   995         nodes[n.id].prev != -2;
   996     }
   997 
   998     bool valid(Arc a) const {
   999       return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
  1000         arcs[a.id].prev_out != -2;
  1001     }
  1002 
  1003     bool valid(Edge e) const {
  1004       return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
  1005         arcs[2 * e.id].prev_out != -2;
  1006     }
  1007 
  1008     Node addNode() {
  1009       int n;
  1010 
  1011       if(first_free_node==-1) {
  1012         n = nodes.size();
  1013         nodes.push_back(NodeT());
  1014       } else {
  1015         n = first_free_node;
  1016         first_free_node = nodes[n].next;
  1017       }
  1018 
  1019       nodes[n].next = first_node;
  1020       if (first_node != -1) nodes[first_node].prev = n;
  1021       first_node = n;
  1022       nodes[n].prev = -1;
  1023 
  1024       nodes[n].first_out = -1;
  1025 
  1026       return Node(n);
  1027     }
  1028 
  1029     Edge addEdge(Node u, Node v) {
  1030       int n;
  1031 
  1032       if (first_free_arc == -1) {
  1033         n = arcs.size();
  1034         arcs.push_back(ArcT());
  1035         arcs.push_back(ArcT());
  1036       } else {
  1037         n = first_free_arc;
  1038         first_free_arc = arcs[n].next_out;
  1039       }
  1040 
  1041       arcs[n].target = u.id;
  1042       arcs[n | 1].target = v.id;
  1043 
  1044       arcs[n].next_out = nodes[v.id].first_out;
  1045       if (nodes[v.id].first_out != -1) {
  1046         arcs[nodes[v.id].first_out].prev_out = n;
  1047       }
  1048       arcs[n].prev_out = -1;
  1049       nodes[v.id].first_out = n;
  1050 
  1051       arcs[n | 1].next_out = nodes[u.id].first_out;
  1052       if (nodes[u.id].first_out != -1) {
  1053         arcs[nodes[u.id].first_out].prev_out = (n | 1);
  1054       }
  1055       arcs[n | 1].prev_out = -1;
  1056       nodes[u.id].first_out = (n | 1);
  1057 
  1058       return Edge(n / 2);
  1059     }
  1060 
  1061     void erase(const Node& node) {
  1062       int n = node.id;
  1063 
  1064       if(nodes[n].next != -1) {
  1065         nodes[nodes[n].next].prev = nodes[n].prev;
  1066       }
  1067 
  1068       if(nodes[n].prev != -1) {
  1069         nodes[nodes[n].prev].next = nodes[n].next;
  1070       } else {
  1071         first_node = nodes[n].next;
  1072       }
  1073 
  1074       nodes[n].next = first_free_node;
  1075       first_free_node = n;
  1076       nodes[n].prev = -2;
  1077     }
  1078 
  1079     void erase(const Edge& edge) {
  1080       int n = edge.id * 2;
  1081 
  1082       if (arcs[n].next_out != -1) {
  1083         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
  1084       }
  1085 
  1086       if (arcs[n].prev_out != -1) {
  1087         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
  1088       } else {
  1089         nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
  1090       }
  1091 
  1092       if (arcs[n | 1].next_out != -1) {
  1093         arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
  1094       }
  1095 
  1096       if (arcs[n | 1].prev_out != -1) {
  1097         arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
  1098       } else {
  1099         nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
  1100       }
  1101 
  1102       arcs[n].next_out = first_free_arc;
  1103       first_free_arc = n;
  1104       arcs[n].prev_out = -2;
  1105       arcs[n | 1].prev_out = -2;
  1106 
  1107     }
  1108 
  1109     void clear() {
  1110       arcs.clear();
  1111       nodes.clear();
  1112       first_node = first_free_node = first_free_arc = -1;
  1113     }
  1114 
  1115   protected:
  1116 
  1117     void changeTarget(Edge e, Node n) {
  1118       if(arcs[2 * e.id].next_out != -1) {
  1119         arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
  1120       }
  1121       if(arcs[2 * e.id].prev_out != -1) {
  1122         arcs[arcs[2 * e.id].prev_out].next_out =
  1123           arcs[2 * e.id].next_out;
  1124       } else {
  1125         nodes[arcs[(2 * e.id) | 1].target].first_out =
  1126           arcs[2 * e.id].next_out;
  1127       }
  1128 
  1129       if (nodes[n.id].first_out != -1) {
  1130         arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
  1131       }
  1132       arcs[(2 * e.id) | 1].target = n.id;
  1133       arcs[2 * e.id].prev_out = -1;
  1134       arcs[2 * e.id].next_out = nodes[n.id].first_out;
  1135       nodes[n.id].first_out = 2 * e.id;
  1136     }
  1137 
  1138     void changeSource(Edge e, Node n) {
  1139       if(arcs[(2 * e.id) | 1].next_out != -1) {
  1140         arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
  1141           arcs[(2 * e.id) | 1].prev_out;
  1142       }
  1143       if(arcs[(2 * e.id) | 1].prev_out != -1) {
  1144         arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
  1145           arcs[(2 * e.id) | 1].next_out;
  1146       } else {
  1147         nodes[arcs[2 * e.id].target].first_out =
  1148           arcs[(2 * e.id) | 1].next_out;
  1149       }
  1150 
  1151       if (nodes[n.id].first_out != -1) {
  1152         arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
  1153       }
  1154       arcs[2 * e.id].target = n.id;
  1155       arcs[(2 * e.id) | 1].prev_out = -1;
  1156       arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
  1157       nodes[n.id].first_out = ((2 * e.id) | 1);
  1158     }
  1159 
  1160   };
  1161 
  1162   typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
  1163 
  1164 
  1165   /// \addtogroup graphs
  1166   /// @{
  1167 
  1168   ///A general undirected graph structure.
  1169 
  1170   ///\ref ListGraph is a simple and fast <em>undirected graph</em>
  1171   ///implementation based on static linked lists that are stored in
  1172   ///\c std::vector structures.
  1173   ///
  1174   ///It conforms to the \ref concepts::Graph "Graph concept" and it
  1175   ///also provides several useful additional functionalities.
  1176   ///Most of the member functions and nested classes are documented
  1177   ///only in the concept class.
  1178   ///
  1179   ///An important extra feature of this graph implementation is that
  1180   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
  1181   ///
  1182   ///\sa concepts::Graph
  1183 
  1184   class ListGraph : public ExtendedListGraphBase {
  1185   private:
  1186     ///ListGraph is \e not copy constructible. Use copyGraph() instead.
  1187 
  1188     ///ListGraph is \e not copy constructible. Use copyGraph() instead.
  1189     ///
  1190     ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
  1191     ///\brief Assignment of ListGraph to another one is \e not allowed.
  1192     ///Use copyGraph() instead.
  1193 
  1194     ///Assignment of ListGraph to another one is \e not allowed.
  1195     ///Use copyGraph() instead.
  1196     void operator=(const ListGraph &) {}
  1197   public:
  1198     /// Constructor
  1199 
  1200     /// Constructor.
  1201     ///
  1202     ListGraph() {}
  1203 
  1204     typedef ExtendedListGraphBase Parent;
  1205 
  1206     typedef Parent::OutArcIt IncEdgeIt;
  1207 
  1208     /// \brief Add a new node to the graph.
  1209     ///
  1210     /// Add a new node to the graph.
  1211     /// \return the new node.
  1212     Node addNode() { return Parent::addNode(); }
  1213 
  1214     /// \brief Add a new edge to the graph.
  1215     ///
  1216     /// Add a new edge to the graph with source node \c s
  1217     /// and target node \c t.
  1218     /// \return the new edge.
  1219     Edge addEdge(const Node& s, const Node& t) {
  1220       return Parent::addEdge(s, t);
  1221     }
  1222 
  1223     /// \brief Erase a node from the graph.
  1224     ///
  1225     /// Erase a node from the graph.
  1226     ///
  1227     void erase(const Node& n) { Parent::erase(n); }
  1228 
  1229     /// \brief Erase an edge from the graph.
  1230     ///
  1231     /// Erase an edge from the graph.
  1232     ///
  1233     void erase(const Edge& e) { Parent::erase(e); }
  1234     /// Node validity check
  1235 
  1236     /// This function gives back true if the given node is valid,
  1237     /// ie. it is a real node of the graph.
  1238     ///
  1239     /// \warning A Node pointing to a removed item
  1240     /// could become valid again later if new nodes are
  1241     /// added to the graph.
  1242     bool valid(Node n) const { return Parent::valid(n); }
  1243     /// Arc validity check
  1244 
  1245     /// This function gives back true if the given arc is valid,
  1246     /// ie. it is a real arc of the graph.
  1247     ///
  1248     /// \warning An Arc pointing to a removed item
  1249     /// could become valid again later if new edges are
  1250     /// added to the graph.
  1251     bool valid(Arc a) const { return Parent::valid(a); }
  1252     /// Edge validity check
  1253 
  1254     /// This function gives back true if the given edge is valid,
  1255     /// ie. it is a real arc of the graph.
  1256     ///
  1257     /// \warning A Edge pointing to a removed item
  1258     /// could become valid again later if new edges are
  1259     /// added to the graph.
  1260     bool valid(Edge e) const { return Parent::valid(e); }
  1261     /// \brief Change the source of \c e to \c n
  1262     ///
  1263     /// This function changes the source of \c e to \c n.
  1264     ///
  1265     ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
  1266     ///referencing the changed arc remain
  1267     ///valid. However <tt>OutArcIt</tt>s are invalidated.
  1268     ///
  1269     ///\warning This functionality cannot be used together with the
  1270     ///Snapshot feature.
  1271     void changeSource(Edge e, Node n) {
  1272       Parent::changeSource(e,n);
  1273     }
  1274     /// \brief Change the target of \c e to \c n
  1275     ///
  1276     /// This function changes the target of \c e to \c n.
  1277     ///
  1278     /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
  1279     /// valid. However the other iterators may be invalidated.
  1280     ///
  1281     ///\warning This functionality cannot be used together with the
  1282     ///Snapshot feature.
  1283     void changeTarget(Edge e, Node n) {
  1284       Parent::changeTarget(e,n);
  1285     }
  1286     /// \brief Change the source of \c e to \c n
  1287     ///
  1288     /// This function changes the source of \c e to \c n.
  1289     /// It also changes the proper node of the represented edge.
  1290     ///
  1291     ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
  1292     ///referencing the changed arc remain
  1293     ///valid. However <tt>OutArcIt</tt>s are invalidated.
  1294     ///
  1295     ///\warning This functionality cannot be used together with the
  1296     ///Snapshot feature.
  1297     void changeSource(Arc e, Node n) {
  1298       if (Parent::direction(e)) {
  1299         Parent::changeSource(e,n);
  1300       } else {
  1301         Parent::changeTarget(e,n);
  1302       }
  1303     }
  1304     /// \brief Change the target of \c e to \c n
  1305     ///
  1306     /// This function changes the target of \c e to \c n.
  1307     /// It also changes the proper node of the represented edge.
  1308     ///
  1309     ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
  1310     ///referencing the changed arc remain
  1311     ///valid. However <tt>InArcIt</tt>s are invalidated.
  1312     ///
  1313     ///\warning This functionality cannot be used together with the
  1314     ///Snapshot feature.
  1315     void changeTarget(Arc e, Node n) {
  1316       if (Parent::direction(e)) {
  1317         Parent::changeTarget(e,n);
  1318       } else {
  1319         Parent::changeSource(e,n);
  1320       }
  1321     }
  1322     /// \brief Contract two nodes.
  1323     ///
  1324     /// This function contracts two nodes.
  1325     /// Node \p b will be removed but instead of deleting
  1326     /// its neighboring arcs, they will be joined to \p a.
  1327     /// The last parameter \p r controls whether to remove loops. \c true
  1328     /// means that loops will be removed.
  1329     ///
  1330     /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
  1331     /// valid.
  1332     ///
  1333     ///\warning This functionality cannot be used together with the
  1334     ///Snapshot feature.
  1335     void contract(Node a, Node b, bool r = true) {
  1336       for(IncEdgeIt e(*this, b); e!=INVALID;) {
  1337         IncEdgeIt f = e; ++f;
  1338         if (r && runningNode(e) == a) {
  1339           erase(e);
  1340         } else if (source(e) == b) {
  1341           changeSource(e, a);
  1342         } else {
  1343           changeTarget(e, a);
  1344         }
  1345         e = f;
  1346       }
  1347       erase(b);
  1348     }
  1349 
  1350 
  1351     /// \brief Class to make a snapshot of the graph and restore
  1352     /// it later.
  1353     ///
  1354     /// Class to make a snapshot of the graph and restore it later.
  1355     ///
  1356     /// The newly added nodes and edges can be removed
  1357     /// using the restore() function.
  1358     ///
  1359     /// \warning Edge and node deletions and other modifications
  1360     /// (e.g. changing nodes of edges, contracting nodes) cannot be
  1361     /// restored. These events invalidate the snapshot.
  1362     class Snapshot {
  1363     protected:
  1364 
  1365       typedef Parent::NodeNotifier NodeNotifier;
  1366 
  1367       class NodeObserverProxy : public NodeNotifier::ObserverBase {
  1368       public:
  1369 
  1370         NodeObserverProxy(Snapshot& _snapshot)
  1371           : snapshot(_snapshot) {}
  1372 
  1373         using NodeNotifier::ObserverBase::attach;
  1374         using NodeNotifier::ObserverBase::detach;
  1375         using NodeNotifier::ObserverBase::attached;
  1376 
  1377       protected:
  1378 
  1379         virtual void add(const Node& node) {
  1380           snapshot.addNode(node);
  1381         }
  1382         virtual void add(const std::vector<Node>& nodes) {
  1383           for (int i = nodes.size() - 1; i >= 0; ++i) {
  1384             snapshot.addNode(nodes[i]);
  1385           }
  1386         }
  1387         virtual void erase(const Node& node) {
  1388           snapshot.eraseNode(node);
  1389         }
  1390         virtual void erase(const std::vector<Node>& nodes) {
  1391           for (int i = 0; i < int(nodes.size()); ++i) {
  1392             snapshot.eraseNode(nodes[i]);
  1393           }
  1394         }
  1395         virtual void build() {
  1396           Node node;
  1397           std::vector<Node> nodes;
  1398           for (notifier()->first(node); node != INVALID;
  1399                notifier()->next(node)) {
  1400             nodes.push_back(node);
  1401           }
  1402           for (int i = nodes.size() - 1; i >= 0; --i) {
  1403             snapshot.addNode(nodes[i]);
  1404           }
  1405         }
  1406         virtual void clear() {
  1407           Node node;
  1408           for (notifier()->first(node); node != INVALID;
  1409                notifier()->next(node)) {
  1410             snapshot.eraseNode(node);
  1411           }
  1412         }
  1413 
  1414         Snapshot& snapshot;
  1415       };
  1416 
  1417       class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
  1418       public:
  1419 
  1420         EdgeObserverProxy(Snapshot& _snapshot)
  1421           : snapshot(_snapshot) {}
  1422 
  1423         using EdgeNotifier::ObserverBase::attach;
  1424         using EdgeNotifier::ObserverBase::detach;
  1425         using EdgeNotifier::ObserverBase::attached;
  1426 
  1427       protected:
  1428 
  1429         virtual void add(const Edge& edge) {
  1430           snapshot.addEdge(edge);
  1431         }
  1432         virtual void add(const std::vector<Edge>& edges) {
  1433           for (int i = edges.size() - 1; i >= 0; ++i) {
  1434             snapshot.addEdge(edges[i]);
  1435           }
  1436         }
  1437         virtual void erase(const Edge& edge) {
  1438           snapshot.eraseEdge(edge);
  1439         }
  1440         virtual void erase(const std::vector<Edge>& edges) {
  1441           for (int i = 0; i < int(edges.size()); ++i) {
  1442             snapshot.eraseEdge(edges[i]);
  1443           }
  1444         }
  1445         virtual void build() {
  1446           Edge edge;
  1447           std::vector<Edge> edges;
  1448           for (notifier()->first(edge); edge != INVALID;
  1449                notifier()->next(edge)) {
  1450             edges.push_back(edge);
  1451           }
  1452           for (int i = edges.size() - 1; i >= 0; --i) {
  1453             snapshot.addEdge(edges[i]);
  1454           }
  1455         }
  1456         virtual void clear() {
  1457           Edge edge;
  1458           for (notifier()->first(edge); edge != INVALID;
  1459                notifier()->next(edge)) {
  1460             snapshot.eraseEdge(edge);
  1461           }
  1462         }
  1463 
  1464         Snapshot& snapshot;
  1465       };
  1466 
  1467       ListGraph *graph;
  1468 
  1469       NodeObserverProxy node_observer_proxy;
  1470       EdgeObserverProxy edge_observer_proxy;
  1471 
  1472       std::list<Node> added_nodes;
  1473       std::list<Edge> added_edges;
  1474 
  1475 
  1476       void addNode(const Node& node) {
  1477         added_nodes.push_front(node);
  1478       }
  1479       void eraseNode(const Node& node) {
  1480         std::list<Node>::iterator it =
  1481           std::find(added_nodes.begin(), added_nodes.end(), node);
  1482         if (it == added_nodes.end()) {
  1483           clear();
  1484           edge_observer_proxy.detach();
  1485           throw NodeNotifier::ImmediateDetach();
  1486         } else {
  1487           added_nodes.erase(it);
  1488         }
  1489       }
  1490 
  1491       void addEdge(const Edge& edge) {
  1492         added_edges.push_front(edge);
  1493       }
  1494       void eraseEdge(const Edge& edge) {
  1495         std::list<Edge>::iterator it =
  1496           std::find(added_edges.begin(), added_edges.end(), edge);
  1497         if (it == added_edges.end()) {
  1498           clear();
  1499           node_observer_proxy.detach();
  1500           throw EdgeNotifier::ImmediateDetach();
  1501         } else {
  1502           added_edges.erase(it);
  1503         }
  1504       }
  1505 
  1506       void attach(ListGraph &_graph) {
  1507         graph = &_graph;
  1508         node_observer_proxy.attach(graph->notifier(Node()));
  1509         edge_observer_proxy.attach(graph->notifier(Edge()));
  1510       }
  1511 
  1512       void detach() {
  1513         node_observer_proxy.detach();
  1514         edge_observer_proxy.detach();
  1515       }
  1516 
  1517       bool attached() const {
  1518         return node_observer_proxy.attached();
  1519       }
  1520 
  1521       void clear() {
  1522         added_nodes.clear();
  1523         added_edges.clear();
  1524       }
  1525 
  1526     public:
  1527 
  1528       /// \brief Default constructor.
  1529       ///
  1530       /// Default constructor.
  1531       /// To actually make a snapshot you must call save().
  1532       Snapshot()
  1533         : graph(0), node_observer_proxy(*this),
  1534           edge_observer_proxy(*this) {}
  1535 
  1536       /// \brief Constructor that immediately makes a snapshot.
  1537       ///
  1538       /// This constructor immediately makes a snapshot of the graph.
  1539       /// \param _graph The graph we make a snapshot of.
  1540       Snapshot(ListGraph &_graph)
  1541         : node_observer_proxy(*this),
  1542           edge_observer_proxy(*this) {
  1543         attach(_graph);
  1544       }
  1545 
  1546       /// \brief Make a snapshot.
  1547       ///
  1548       /// Make a snapshot of the graph.
  1549       ///
  1550       /// This function can be called more than once. In case of a repeated
  1551       /// call, the previous snapshot gets lost.
  1552       /// \param _graph The graph we make the snapshot of.
  1553       void save(ListGraph &_graph) {
  1554         if (attached()) {
  1555           detach();
  1556           clear();
  1557         }
  1558         attach(_graph);
  1559       }
  1560 
  1561       /// \brief Undo the changes until the last snapshot.
  1562       //
  1563       /// Undo the changes until the last snapshot created by save().
  1564       void restore() {
  1565         detach();
  1566         for(std::list<Edge>::iterator it = added_edges.begin();
  1567             it != added_edges.end(); ++it) {
  1568           graph->erase(*it);
  1569         }
  1570         for(std::list<Node>::iterator it = added_nodes.begin();
  1571             it != added_nodes.end(); ++it) {
  1572           graph->erase(*it);
  1573         }
  1574         clear();
  1575       }
  1576 
  1577       /// \brief Gives back true when the snapshot is valid.
  1578       ///
  1579       /// Gives back true when the snapshot is valid.
  1580       bool valid() const {
  1581         return attached();
  1582       }
  1583     };
  1584   };
  1585 
  1586   /// @}
  1587 } //namespace lemon
  1588 
  1589 
  1590 #endif