lemon/list_graph.h
author deba
Thu, 11 Jan 2007 21:06:47 +0000
changeset 2338 359f0b71919b
parent 2302 d3c664c975ee
child 2342 4dd3eb348641
permissions -rw-r--r--
Changing implementation of undirected graphs
slightly faster, 10% speed-up
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     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 ListGraph, ListUGraph classes.
    25 
    26 #include <lemon/bits/base_extender.h>
    27 #include <lemon/bits/graph_extender.h>
    28 
    29 #include <lemon/error.h>
    30 
    31 #include <vector>
    32 #include <list>
    33 
    34 namespace lemon {
    35 
    36   class ListGraphBase {
    37 
    38   protected:
    39     struct NodeT {
    40       int first_in, first_out;
    41       int prev, next;
    42     };
    43  
    44     struct EdgeT {
    45       int target, source;
    46       int prev_in, prev_out;
    47       int next_in, next_out;
    48     };
    49 
    50     std::vector<NodeT> nodes;
    51 
    52     int first_node;
    53 
    54     int first_free_node;
    55 
    56     std::vector<EdgeT> edges;
    57 
    58     int first_free_edge;
    59     
    60   public:
    61     
    62     typedef ListGraphBase Graph;
    63     
    64     class Node {
    65       friend class ListGraphBase;
    66     protected:
    67 
    68       int id;
    69       explicit Node(int pid) { id = pid;}
    70 
    71     public:
    72       Node() {}
    73       Node (Invalid) { id = -1; }
    74       bool operator==(const Node& node) const {return id == node.id;}
    75       bool operator!=(const Node& node) const {return id != node.id;}
    76       bool operator<(const Node& node) const {return id < node.id;}
    77     };
    78 
    79     class Edge {
    80       friend class ListGraphBase;
    81     protected:
    82 
    83       int id;
    84       explicit Edge(int pid) { id = pid;}
    85 
    86     public:
    87       Edge() {}
    88       Edge (Invalid) { id = -1; }
    89       bool operator==(const Edge& edge) const {return id == edge.id;}
    90       bool operator!=(const Edge& edge) const {return id != edge.id;}
    91       bool operator<(const Edge& edge) const {return id < edge.id;}
    92     };
    93 
    94 
    95 
    96     ListGraphBase()
    97       : nodes(), first_node(-1),
    98 	first_free_node(-1), edges(), first_free_edge(-1) {}
    99 
   100     
   101     int maxNodeId() const { return nodes.size()-1; } 
   102     int maxEdgeId() const { return edges.size()-1; }
   103 
   104     Node source(Edge e) const { return Node(edges[e.id].source); }
   105     Node target(Edge e) const { return Node(edges[e.id].target); }
   106 
   107 
   108     void first(Node& node) const { 
   109       node.id = first_node;
   110     }
   111 
   112     void next(Node& node) const {
   113       node.id = nodes[node.id].next;
   114     }
   115 
   116 
   117     void first(Edge& e) const { 
   118       int n;
   119       for(n = first_node; 
   120 	  n!=-1 && nodes[n].first_in == -1; 
   121 	  n = nodes[n].next);
   122       e.id = (n == -1) ? -1 : nodes[n].first_in;
   123     }
   124 
   125     void next(Edge& edge) const {
   126       if (edges[edge.id].next_in != -1) {
   127 	edge.id = edges[edge.id].next_in;
   128       } else {
   129 	int n;
   130 	for(n = nodes[edges[edge.id].target].next;
   131 	  n!=-1 && nodes[n].first_in == -1; 
   132 	  n = nodes[n].next);
   133 	edge.id = (n == -1) ? -1 : nodes[n].first_in;
   134       }      
   135     }
   136 
   137     void firstOut(Edge &e, const Node& v) const {
   138       e.id = nodes[v.id].first_out;
   139     }
   140     void nextOut(Edge &e) const {
   141       e.id=edges[e.id].next_out;
   142     }
   143 
   144     void firstIn(Edge &e, const Node& v) const {
   145       e.id = nodes[v.id].first_in;
   146     }
   147     void nextIn(Edge &e) const {
   148       e.id=edges[e.id].next_in;
   149     }
   150 
   151     
   152     static int id(Node v) { return v.id; }
   153     static int id(Edge e) { return e.id; }
   154 
   155     static Node nodeFromId(int id) { return Node(id);}
   156     static Edge edgeFromId(int id) { return Edge(id);}
   157 
   158     Node addNode() {     
   159       int n;
   160       
   161       if(first_free_node==-1) {
   162 	n = nodes.size();
   163 	nodes.push_back(NodeT());
   164       } else {
   165 	n = first_free_node;
   166 	first_free_node = nodes[n].next;
   167       }
   168       
   169       nodes[n].next = first_node;
   170       if(first_node != -1) nodes[first_node].prev = n;
   171       first_node = n;
   172       nodes[n].prev = -1;
   173       
   174       nodes[n].first_in = nodes[n].first_out = -1;
   175       
   176       return Node(n);
   177     }
   178     
   179     Edge addEdge(Node u, Node v) {
   180       int n;      
   181 
   182       if (first_free_edge == -1) {
   183 	n = edges.size();
   184 	edges.push_back(EdgeT());
   185       } else {
   186 	n = first_free_edge;
   187 	first_free_edge = edges[n].next_in;
   188       }
   189       
   190       edges[n].source = u.id; 
   191       edges[n].target = v.id;
   192 
   193       edges[n].next_out = nodes[u.id].first_out;
   194       if(nodes[u.id].first_out != -1) {
   195 	edges[nodes[u.id].first_out].prev_out = n;
   196       }
   197       
   198       edges[n].next_in = nodes[v.id].first_in;
   199       if(nodes[v.id].first_in != -1) {
   200 	edges[nodes[v.id].first_in].prev_in = n;
   201       }
   202       
   203       edges[n].prev_in = edges[n].prev_out = -1;
   204 	
   205       nodes[u.id].first_out = nodes[v.id].first_in = n;
   206 
   207       return Edge(n);
   208     }
   209     
   210     void erase(const Node& node) {
   211       int n = node.id;
   212       
   213       if(nodes[n].next != -1) {
   214 	nodes[nodes[n].next].prev = nodes[n].prev;
   215       }
   216       
   217       if(nodes[n].prev != -1) {
   218 	nodes[nodes[n].prev].next = nodes[n].next;
   219       } else {
   220 	first_node = nodes[n].next;
   221       }
   222       
   223       nodes[n].next = first_free_node;
   224       first_free_node = n;
   225 
   226     }
   227     
   228     void erase(const Edge& edge) {
   229       int n = edge.id;
   230       
   231       if(edges[n].next_in!=-1) {
   232 	edges[edges[n].next_in].prev_in = edges[n].prev_in;
   233       }
   234 
   235       if(edges[n].prev_in!=-1) {
   236 	edges[edges[n].prev_in].next_in = edges[n].next_in;
   237       } else {
   238 	nodes[edges[n].target].first_in = edges[n].next_in;
   239       }
   240 
   241       
   242       if(edges[n].next_out!=-1) {
   243 	edges[edges[n].next_out].prev_out = edges[n].prev_out;
   244       } 
   245 
   246       if(edges[n].prev_out!=-1) {
   247 	edges[edges[n].prev_out].next_out = edges[n].next_out;
   248       } else {
   249 	nodes[edges[n].source].first_out = edges[n].next_out;
   250       }
   251       
   252       edges[n].next_in = first_free_edge;
   253       first_free_edge = n;      
   254 
   255     }
   256 
   257     void clear() {
   258       edges.clear();
   259       nodes.clear();
   260       first_node = first_free_node = first_free_edge = -1;
   261     }
   262 
   263   protected:
   264     void changeTarget(Edge e, Node n) 
   265     {
   266       if(edges[e.id].next_in != -1)
   267 	edges[edges[e.id].next_in].prev_in = edges[e.id].prev_in;
   268       if(edges[e.id].prev_in != -1)
   269 	edges[edges[e.id].prev_in].next_in = edges[e.id].next_in;
   270       else nodes[edges[e.id].target].first_in = edges[e.id].next_in;
   271       if (nodes[n.id].first_in != -1) {
   272 	edges[nodes[n.id].first_in].prev_in = e.id;
   273       }
   274       edges[e.id].target = n.id;
   275       edges[e.id].prev_in = -1;
   276       edges[e.id].next_in = nodes[n.id].first_in;
   277       nodes[n.id].first_in = e.id;
   278     }
   279     void changeSource(Edge e, Node n) 
   280     {
   281       if(edges[e.id].next_out != -1)
   282 	edges[edges[e.id].next_out].prev_out = edges[e.id].prev_out;
   283       if(edges[e.id].prev_out != -1)
   284 	edges[edges[e.id].prev_out].next_out = edges[e.id].next_out;
   285       else nodes[edges[e.id].source].first_out = edges[e.id].next_out;
   286       if (nodes[n.id].first_out != -1) {
   287 	edges[nodes[n.id].first_out].prev_out = e.id;
   288       }
   289       edges[e.id].source = n.id;
   290       edges[e.id].prev_out = -1;
   291       edges[e.id].next_out = nodes[n.id].first_out;
   292       nodes[n.id].first_out = e.id;
   293     }
   294 
   295   };
   296 
   297   typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
   298 
   299   /// \addtogroup graphs
   300   /// @{
   301 
   302   ///A list graph class.
   303 
   304   ///This is a simple and fast graph implementation.
   305   ///
   306   ///It conforms to the \ref concepts::Graph "Graph concept" and it
   307   ///also provides several additional useful extra functionalities.
   308   ///The most of the member functions and nested classes are
   309   ///documented only in the concept class.
   310   ///
   311   ///An important extra feature of this graph implementation is that
   312   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
   313   ///
   314   ///\sa concepts::Graph.
   315 
   316   class ListGraph : public ExtendedListGraphBase {
   317   private:
   318     ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
   319     
   320     ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
   321     ///
   322     ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
   323     ///\brief Assignment of ListGraph to another one is \e not allowed.
   324     ///Use GraphCopy() instead.
   325 
   326     ///Assignment of ListGraph to another one is \e not allowed.
   327     ///Use GraphCopy() instead.
   328     void operator=(const ListGraph &) {}
   329   public:
   330 
   331     typedef ExtendedListGraphBase Parent;
   332 
   333     /// Constructor
   334     
   335     /// Constructor.
   336     ///
   337     ListGraph() {}
   338 
   339     ///Add a new node to the graph.
   340     
   341     /// \return the new node.
   342     ///
   343     Node addNode() { return Parent::addNode(); }
   344 
   345     ///Add a new edge to the graph.
   346     
   347     ///Add a new edge to the graph with source node \c s
   348     ///and target node \c t.
   349     ///\return the new edge.
   350     Edge addEdge(const Node& s, const Node& t) { 
   351       return Parent::addEdge(s, t); 
   352     }
   353 
   354     /// Changes the target of \c e to \c n
   355 
   356     /// Changes the target of \c e to \c n
   357     ///
   358     ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s referencing
   359     ///the changed edge remain valid. However <tt>InEdgeIt</tt>s are
   360     ///invalidated.
   361     ///\warning This functionality cannot be used together with the Snapshot
   362     ///feature.
   363     void changeTarget(Edge e, Node n) { 
   364       Parent::changeTarget(e,n); 
   365     }
   366     /// Changes the source of \c e to \c n
   367 
   368     /// Changes the source of \c e to \c n
   369     ///
   370     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
   371     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
   372     ///invalidated.
   373     ///\warning This functionality cannot be used together with the Snapshot
   374     ///feature.
   375     void changeSource(Edge e, Node n) { 
   376       Parent::changeSource(e,n);
   377     }
   378 
   379     /// Invert the direction of an edge.
   380 
   381     ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
   382     ///valid. However <tt>OutEdgeIt</tt>s and <tt>InEdgeIt</tt>s are
   383     ///invalidated.
   384     ///\warning This functionality cannot be used together with the Snapshot
   385     ///feature.
   386     void reverseEdge(Edge e) {
   387       Node t=target(e);
   388       changeTarget(e,source(e));
   389       changeSource(e,t);
   390     }
   391 
   392     /// \brief Using this it is possible to avoid the superfluous memory
   393     /// allocation.
   394 
   395     ///Using this it is possible to avoid the superfluous memory
   396     ///allocation: if you know that the graph you want to build will
   397     ///contain at least 10 million nodes then it is worth reserving
   398     ///space for this amount before starting to build the graph.
   399     void reserveNode(int n) { nodes.reserve(n); };
   400 
   401     /// \brief Using this it is possible to avoid the superfluous memory
   402     /// allocation.
   403 
   404     ///Using this it is possible to avoid the superfluous memory
   405     ///allocation: see the \ref reserveNode function.
   406     void reserveEdge(int n) { edges.reserve(n); };
   407 
   408 
   409     ///Contract two nodes.
   410 
   411     ///This function contracts two nodes.
   412     ///
   413     ///Node \p b will be removed but instead of deleting
   414     ///incident edges, they will be joined to \p a.
   415     ///The last parameter \p r controls whether to remove loops. \c true
   416     ///means that loops will be removed.
   417     ///
   418     ///\note The <tt>EdgeIt</tt>s
   419     ///referencing a moved edge remain
   420     ///valid. However <tt>InEdgeIt</tt>s and <tt>OutEdgeIt</tt>s
   421     ///may be invalidated.
   422     ///\warning This functionality cannot be used together with the Snapshot
   423     ///feature.
   424     void contract(Node a, Node b, bool r = true) 
   425     {
   426       for(OutEdgeIt e(*this,b);e!=INVALID;) {
   427 	OutEdgeIt f=e;
   428 	++f;
   429 	if(r && target(e)==a) erase(e);
   430 	else changeSource(e,a);
   431 	e=f;
   432       }
   433       for(InEdgeIt e(*this,b);e!=INVALID;) {
   434 	InEdgeIt f=e;
   435 	++f;
   436 	if(r && source(e)==a) erase(e);
   437 	else changeTarget(e,a);
   438 	e=f;
   439       }
   440       erase(b);
   441     }
   442 
   443     ///Split a node.
   444 
   445     ///This function splits a node. First a new node is added to the graph,
   446     ///then the source of each outgoing edge of \c n is moved to this new node.
   447     ///If \c connect is \c true (this is the default value), then a new edge
   448     ///from \c n to the newly created node is also added.
   449     ///\return The newly created node.
   450     ///
   451     ///\note The <tt>EdgeIt</tt>s referencing a moved edge remain
   452     ///valid. However <tt>InEdgeIt</tt>s and <tt>OutEdgeIt</tt>s may
   453     ///be invalidated.  
   454     ///
   455     ///\warning This functionality cannot be used together with the
   456     ///Snapshot feature.  \todo It could be implemented in a bit
   457     ///faster way.
   458     Node split(Node n, bool connect = true) {
   459       Node b = addNode();
   460       for(OutEdgeIt e(*this,n);e!=INVALID;) {
   461  	OutEdgeIt f=e;
   462 	++f;
   463 	changeSource(e,b);
   464 	e=f;
   465       }
   466       if (connect) addEdge(n,b);
   467       return b;
   468     }
   469       
   470     ///Split an edge.
   471 
   472     ///This function splits an edge. First a new node \c b is added to
   473     ///the graph, then the original edge is re-targeted to \c
   474     ///b. Finally an edge from \c b to the original target is added.
   475     ///\return The newly created node.  
   476     ///\warning This functionality
   477     ///cannot be used together with the Snapshot feature.
   478     Node split(Edge e) {
   479       Node b = addNode();
   480       addEdge(b,target(e));
   481       changeTarget(e,b);
   482       return b;
   483     }
   484       
   485     /// \brief Class to make a snapshot of the graph and restore
   486     /// to it later.
   487     ///
   488     /// Class to make a snapshot of the graph and to restore it
   489     /// later.
   490     ///
   491     /// The newly added nodes and edges can be removed using the
   492     /// restore() function.
   493     ///
   494     /// \warning Edge and node deletions cannot be restored. This
   495     /// events invalidate the snapshot. 
   496     class Snapshot {
   497     protected:
   498 
   499       typedef Parent::NodeNotifier NodeNotifier;
   500 
   501       class NodeObserverProxy : public NodeNotifier::ObserverBase {
   502       public:
   503 
   504         NodeObserverProxy(Snapshot& _snapshot)
   505           : snapshot(_snapshot) {}
   506 
   507         using NodeNotifier::ObserverBase::attach;
   508         using NodeNotifier::ObserverBase::detach;
   509         using NodeNotifier::ObserverBase::attached;
   510         
   511       protected:
   512         
   513         virtual void add(const Node& node) {
   514           snapshot.addNode(node);
   515         }
   516         virtual void add(const std::vector<Node>& nodes) {
   517           for (int i = nodes.size() - 1; i >= 0; ++i) {
   518             snapshot.addNode(nodes[i]);
   519           }
   520         }
   521         virtual void erase(const Node& node) {
   522           snapshot.eraseNode(node);
   523         }
   524         virtual void erase(const std::vector<Node>& nodes) {
   525           for (int i = 0; i < (int)nodes.size(); ++i) {
   526             snapshot.eraseNode(nodes[i]);
   527           }
   528         }
   529         virtual void build() {
   530           NodeNotifier* notifier = getNotifier();
   531           Node node;
   532           std::vector<Node> nodes;
   533           for (notifier->first(node); node != INVALID; notifier->next(node)) {
   534             nodes.push_back(node);
   535           }
   536           for (int i = nodes.size() - 1; i >= 0; --i) {
   537             snapshot.addNode(nodes[i]);
   538           }
   539         }
   540         virtual void clear() {
   541           NodeNotifier* notifier = getNotifier();
   542           Node node;
   543           for (notifier->first(node); node != INVALID; notifier->next(node)) {
   544             snapshot.eraseNode(node);
   545           }
   546         }
   547 
   548         Snapshot& snapshot;
   549       };
   550 
   551       class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
   552       public:
   553 
   554         EdgeObserverProxy(Snapshot& _snapshot)
   555           : snapshot(_snapshot) {}
   556 
   557         using EdgeNotifier::ObserverBase::attach;
   558         using EdgeNotifier::ObserverBase::detach;
   559         using EdgeNotifier::ObserverBase::attached;
   560         
   561       protected:
   562 
   563         virtual void add(const Edge& edge) {
   564           snapshot.addEdge(edge);
   565         }
   566         virtual void add(const std::vector<Edge>& edges) {
   567           for (int i = edges.size() - 1; i >= 0; ++i) {
   568             snapshot.addEdge(edges[i]);
   569           }
   570         }
   571         virtual void erase(const Edge& edge) {
   572           snapshot.eraseEdge(edge);
   573         }
   574         virtual void erase(const std::vector<Edge>& edges) {
   575           for (int i = 0; i < (int)edges.size(); ++i) {
   576             snapshot.eraseEdge(edges[i]);
   577           }
   578         }
   579         virtual void build() {
   580           EdgeNotifier* notifier = getNotifier();
   581           Edge edge;
   582           std::vector<Edge> edges;
   583           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
   584             edges.push_back(edge);
   585           }
   586           for (int i = edges.size() - 1; i >= 0; --i) {
   587             snapshot.addEdge(edges[i]);
   588           }
   589         }
   590         virtual void clear() {
   591           EdgeNotifier* notifier = getNotifier();
   592           Edge edge;
   593           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
   594             snapshot.eraseEdge(edge);
   595           }
   596         }
   597 
   598         Snapshot& snapshot;
   599       };
   600       
   601       ListGraph *graph;
   602 
   603       NodeObserverProxy node_observer_proxy;
   604       EdgeObserverProxy edge_observer_proxy;
   605 
   606       std::list<Node> added_nodes;
   607       std::list<Edge> added_edges;
   608 
   609 
   610       void addNode(const Node& node) {
   611         added_nodes.push_front(node);        
   612       }
   613       void eraseNode(const Node& node) {
   614         std::list<Node>::iterator it = 
   615           std::find(added_nodes.begin(), added_nodes.end(), node);
   616         if (it == added_nodes.end()) {
   617           clear();
   618           edge_observer_proxy.detach();
   619           throw NodeNotifier::ImmediateDetach();
   620         } else {
   621           added_nodes.erase(it);
   622         }
   623       }
   624 
   625       void addEdge(const Edge& edge) {
   626         added_edges.push_front(edge);        
   627       }
   628       void eraseEdge(const Edge& edge) {
   629         std::list<Edge>::iterator it = 
   630           std::find(added_edges.begin(), added_edges.end(), edge);
   631         if (it == added_edges.end()) {
   632           clear();
   633           node_observer_proxy.detach(); 
   634           throw EdgeNotifier::ImmediateDetach();
   635         } else {
   636           added_edges.erase(it);
   637         }        
   638       }
   639 
   640       void attach(ListGraph &_graph) {
   641 	graph = &_graph;
   642 	node_observer_proxy.attach(graph->getNotifier(Node()));
   643         edge_observer_proxy.attach(graph->getNotifier(Edge()));
   644       }
   645             
   646       void detach() {
   647 	node_observer_proxy.detach();
   648 	edge_observer_proxy.detach();
   649       }
   650 
   651       bool attached() const {
   652         return node_observer_proxy.attached();
   653       }
   654 
   655       void clear() {
   656         added_nodes.clear();
   657         added_edges.clear();        
   658       }
   659 
   660     public:
   661 
   662       /// \brief Default constructor.
   663       ///
   664       /// Default constructor.
   665       /// To actually make a snapshot you must call save().
   666       Snapshot() 
   667         : graph(0), node_observer_proxy(*this), 
   668           edge_observer_proxy(*this) {}
   669       
   670       /// \brief Constructor that immediately makes a snapshot.
   671       ///      
   672       /// This constructor immediately makes a snapshot of the graph.
   673       /// \param _graph The graph we make a snapshot of.
   674       Snapshot(ListGraph &_graph) 
   675         : node_observer_proxy(*this), 
   676           edge_observer_proxy(*this) {
   677 	attach(_graph);
   678       }
   679       
   680       /// \brief Make a snapshot.
   681       ///
   682       /// Make a snapshot of the graph.
   683       ///
   684       /// This function can be called more than once. In case of a repeated
   685       /// call, the previous snapshot gets lost.
   686       /// \param _graph The graph we make the snapshot of.
   687       void save(ListGraph &_graph) {
   688         if (attached()) {
   689           detach();
   690           clear();
   691         }
   692         attach(_graph);
   693       }
   694       
   695       /// \brief Undo the changes until the last snapshot.
   696       // 
   697       /// Undo the changes until the last snapshot created by save().
   698       void restore() {
   699 	detach();
   700 	for(std::list<Edge>::iterator it = added_edges.begin(); 
   701             it != added_edges.end(); ++it) {
   702 	  graph->erase(*it);
   703 	}
   704 	for(std::list<Node>::iterator it = added_nodes.begin(); 
   705             it != added_nodes.end(); ++it) {
   706 	  graph->erase(*it);
   707 	}
   708         clear();
   709       }
   710 
   711       /// \brief Gives back true when the snapshot is valid.
   712       ///
   713       /// Gives back true when the snapshot is valid.
   714       bool valid() const {
   715         return attached();
   716       }
   717     };
   718     
   719   };
   720 
   721   ///@}
   722 
   723   class ListUGraphBase {
   724 
   725   protected:
   726 
   727     struct NodeT {
   728       int first_out;
   729       int prev, next;
   730     };
   731  
   732     struct EdgeT {
   733       int target;
   734       int prev_out, next_out;
   735     };
   736 
   737     std::vector<NodeT> nodes;
   738 
   739     int first_node;
   740 
   741     int first_free_node;
   742 
   743     std::vector<EdgeT> edges;
   744 
   745     int first_free_edge;
   746     
   747   public:
   748     
   749     typedef ListUGraphBase Graph;
   750     
   751     class Node {
   752       friend class ListUGraphBase;
   753     protected:
   754 
   755       int id;
   756       explicit Node(int pid) { id = pid;}
   757 
   758     public:
   759       Node() {}
   760       Node (Invalid) { id = -1; }
   761       bool operator==(const Node& node) const {return id == node.id;}
   762       bool operator!=(const Node& node) const {return id != node.id;}
   763       bool operator<(const Node& node) const {return id < node.id;}
   764     };
   765 
   766     class UEdge {
   767       friend class ListUGraphBase;
   768     protected:
   769 
   770       int id;
   771       explicit UEdge(int pid) { id = pid;}
   772 
   773     public:
   774       UEdge() {}
   775       UEdge (Invalid) { id = -1; }
   776       bool operator==(const UEdge& edge) const {return id == edge.id;}
   777       bool operator!=(const UEdge& edge) const {return id != edge.id;}
   778       bool operator<(const UEdge& edge) const {return id < edge.id;}
   779     };
   780 
   781     class Edge {
   782       friend class ListUGraphBase;
   783     protected:
   784 
   785       int id;
   786       explicit Edge(int pid) { id = pid;}
   787 
   788     public:
   789       operator UEdge() const { return UEdge(id / 2); }
   790 
   791       Edge() {}
   792       Edge (Invalid) { id = -1; }
   793       bool operator==(const Edge& edge) const {return id == edge.id;}
   794       bool operator!=(const Edge& edge) const {return id != edge.id;}
   795       bool operator<(const Edge& edge) const {return id < edge.id;}
   796     };
   797 
   798 
   799 
   800     ListUGraphBase()
   801       : nodes(), first_node(-1),
   802 	first_free_node(-1), edges(), first_free_edge(-1) {}
   803 
   804     
   805     int maxNodeId() const { return nodes.size()-1; } 
   806     int maxUEdgeId() const { return edges.size() / 2 - 1; }
   807     int maxEdgeId() const { return edges.size()-1; }
   808 
   809     Node source(Edge e) const { return Node(edges[e.id ^ 1].target); }
   810     Node target(Edge e) const { return Node(edges[e.id].target); }
   811 
   812     Node source(UEdge e) const { return Node(edges[2 * e.id].target); }
   813     Node target(UEdge e) const { return Node(edges[2 * e.id + 1].target); }
   814 
   815     static bool direction(Edge e) {
   816       return (e.id & 1) == 1;
   817     }
   818 
   819     static Edge direct(UEdge e, bool d) {
   820       return Edge(e.id * 2 + (d ? 1 : 0));
   821     }
   822 
   823     void first(Node& node) const { 
   824       node.id = first_node;
   825     }
   826 
   827     void next(Node& node) const {
   828       node.id = nodes[node.id].next;
   829     }
   830 
   831     void first(Edge& e) const { 
   832       int n = first_node;
   833       while (n != -1 && nodes[n].first_out == -1) {
   834         n = nodes[n].next;
   835       }
   836       e.id = (n == -1) ? -1 : nodes[n].first_out;
   837     }
   838 
   839     void next(Edge& e) const {
   840       if (edges[e.id].next_out != -1) {
   841 	e.id = edges[e.id].next_out;
   842       } else {
   843 	int n = nodes[edges[e.id ^ 1].target].next;
   844         while(n != -1 && nodes[n].first_out == -1) {
   845           n = nodes[n].next;
   846         }
   847 	e.id = (n == -1) ? -1 : nodes[n].first_out;
   848       }      
   849     }
   850 
   851     void first(UEdge& e) const { 
   852       int n = first_node;
   853       while (n != -1) {
   854         e.id = nodes[n].first_out;
   855         while ((e.id & 1) != 1) {
   856           e.id = edges[e.id].next_out;
   857         }
   858         if (e.id != -1) {
   859           e.id /= 2;
   860           return;
   861         } 
   862         n = nodes[n].next;
   863       }
   864       e.id = -1;
   865     }
   866 
   867     void next(UEdge& e) const {
   868       int n = edges[e.id * 2].target;
   869       e.id = edges[(e.id * 2) | 1].next_out;
   870       while ((e.id & 1) != 1) {
   871         e.id = edges[e.id].next_out;
   872       }
   873       if (e.id != -1) {
   874         e.id /= 2;
   875         return;
   876       } 
   877       n = nodes[n].next;
   878       while (n != -1) {
   879         e.id = nodes[n].first_out;
   880         while ((e.id & 1) != 1) {
   881           e.id = edges[e.id].next_out;
   882         }
   883         if (e.id != -1) {
   884           e.id /= 2;
   885           return;
   886         } 
   887         n = nodes[n].next;
   888       }
   889       e.id = -1;
   890     }
   891 
   892     void firstOut(Edge &e, const Node& v) const {
   893       e.id = nodes[v.id].first_out;
   894     }
   895     void nextOut(Edge &e) const {
   896       e.id = edges[e.id].next_out;
   897     }
   898 
   899     void firstIn(Edge &e, const Node& v) const {
   900       e.id = ((nodes[v.id].first_out) ^ 1);
   901       if (e.id == -2) e.id = -1;
   902     }
   903     void nextIn(Edge &e) const {
   904       e.id = ((edges[e.id ^ 1].next_out) ^ 1);
   905       if (e.id == -2) e.id = -1;
   906     }
   907 
   908     void firstInc(UEdge &e, bool& d, const Node& v) const {
   909       int de = nodes[v.id].first_out;
   910       e.id = de / 2;
   911       d = ((de & 1) == 1);
   912     }
   913     void nextInc(UEdge &e, bool& d) const {
   914       int de = (edges[(e.id * 2) | (d ? 1 : 0)].next_out);
   915       e.id = de / 2;
   916       d = ((de & 1) == 1);
   917     }
   918     
   919     static int id(Node v) { return v.id; }
   920     static int id(Edge e) { return e.id; }
   921     static int id(UEdge e) { return e.id; }
   922 
   923     static Node nodeFromId(int id) { return Node(id);}
   924     static Edge edgeFromId(int id) { return Edge(id);}
   925     static UEdge uEdgeFromId(int id) { return UEdge(id);}
   926 
   927     Node addNode() {     
   928       int n;
   929       
   930       if(first_free_node==-1) {
   931 	n = nodes.size();
   932 	nodes.push_back(NodeT());
   933       } else {
   934 	n = first_free_node;
   935 	first_free_node = nodes[n].next;
   936       }
   937       
   938       nodes[n].next = first_node;
   939       if (first_node != -1) nodes[first_node].prev = n;
   940       first_node = n;
   941       nodes[n].prev = -1;
   942       
   943       nodes[n].first_out = -1;
   944       
   945       return Node(n);
   946     }
   947     
   948     UEdge addEdge(Node u, Node v) {
   949       int n;      
   950 
   951       if (first_free_edge == -1) {
   952 	n = edges.size();
   953 	edges.push_back(EdgeT());
   954 	edges.push_back(EdgeT());
   955       } else {
   956 	n = first_free_edge;
   957 	first_free_edge = edges[n].next_out;
   958       }
   959       
   960       edges[n].target = u.id;
   961       edges[n | 1].target = v.id;
   962 
   963       edges[n].next_out = nodes[v.id].first_out;
   964       edges[n | 1].next_out = nodes[u.id].first_out;
   965       if (nodes[v.id].first_out != -1) {
   966 	edges[nodes[v.id].first_out].prev_out = n;
   967       }
   968       if (nodes[u.id].first_out != -1) {
   969 	edges[nodes[u.id].first_out].prev_out = (n | 1);
   970       }
   971       
   972       edges[n].prev_out = edges[n | 1].prev_out = -1;
   973 	
   974       nodes[v.id].first_out = n;
   975       nodes[u.id].first_out = (n | 1);
   976 
   977       return UEdge(n / 2);
   978     }
   979     
   980     void erase(const Node& node) {
   981       int n = node.id;
   982       
   983       if(nodes[n].next != -1) {
   984 	nodes[nodes[n].next].prev = nodes[n].prev;
   985       }
   986       
   987       if(nodes[n].prev != -1) {
   988 	nodes[nodes[n].prev].next = nodes[n].next;
   989       } else {
   990 	first_node = nodes[n].next;
   991       }
   992       
   993       nodes[n].next = first_free_node;
   994       first_free_node = n;
   995 
   996     }
   997     
   998     void erase(const UEdge& edge) {
   999       int n = edge.id * 2;
  1000       
  1001       if (edges[n].next_out != -1) {
  1002 	edges[edges[n].next_out].prev_out = edges[n].prev_out;
  1003       } 
  1004 
  1005       if (edges[n].prev_out != -1) {
  1006 	edges[edges[n].prev_out].next_out = edges[n].next_out;
  1007       } else {
  1008 	nodes[edges[n | 1].target].first_out = edges[n].next_out;
  1009       }
  1010 
  1011       if (edges[n | 1].next_out != -1) {
  1012 	edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
  1013       } 
  1014 
  1015       if (edges[n | 1].prev_out != -1) {
  1016 	edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
  1017       } else {
  1018 	nodes[edges[n].target].first_out = edges[n | 1].next_out;
  1019       }
  1020       
  1021       edges[n].next_out = first_free_edge;
  1022       first_free_edge = n;      
  1023 
  1024     }
  1025 
  1026     void clear() {
  1027       edges.clear();
  1028       nodes.clear();
  1029       first_node = first_free_node = first_free_edge = -1;
  1030     }
  1031 
  1032   protected:
  1033 
  1034     void changeTarget(UEdge e, Node n) {
  1035       if(edges[2 * e.id].next_out != -1) {
  1036 	edges[edges[2 * e.id].next_out].prev_out = edges[2 * e.id].prev_out;
  1037       }
  1038       if(edges[2 * e.id].prev_out != -1) {
  1039 	edges[edges[2 * e.id].prev_out].next_out = 
  1040           edges[2 * e.id].next_out;
  1041       } else {
  1042         nodes[edges[(2 * e.id) | 1].target].first_out = 
  1043           edges[2 * e.id].next_out;
  1044       }
  1045 
  1046       if (nodes[n.id].first_out != -1) {
  1047 	edges[nodes[n.id].first_out].prev_out = 2 * e.id;
  1048       }
  1049       edges[(2 * e.id) | 1].target = n.id;
  1050       edges[2 * e.id].prev_out = -1;
  1051       edges[2 * e.id].next_out = nodes[n.id].first_out;
  1052       nodes[n.id].first_out = 2 * e.id;
  1053     }
  1054 
  1055     void changeSource(UEdge e, Node n) {
  1056       if(edges[(2 * e.id) | 1].next_out != -1) {
  1057 	edges[edges[(2 * e.id) | 1].next_out].prev_out = 
  1058           edges[(2 * e.id) | 1].prev_out;
  1059       }
  1060       if(edges[(2 * e.id) | 1].prev_out != -1) {
  1061 	edges[edges[(2 * e.id) | 1].prev_out].next_out = 
  1062           edges[(2 * e.id) | 1].next_out;
  1063       } else {
  1064         nodes[edges[2 * e.id].target].first_out = 
  1065           edges[(2 * e.id) | 1].next_out;
  1066       }
  1067 
  1068       if (nodes[n.id].first_out != -1) {
  1069 	edges[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
  1070       }
  1071       edges[2 * e.id].target = n.id;
  1072       edges[(2 * e.id) | 1].prev_out = -1;
  1073       edges[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
  1074       nodes[n.id].first_out = ((2 * e.id) | 1);
  1075     }
  1076 
  1077   };
  1078 
  1079 //   typedef UGraphExtender<UndirGraphExtender<ListGraphBase> > 
  1080 //   ExtendedListUGraphBase;
  1081 
  1082   typedef UGraphExtender<ListUGraphBase> ExtendedListUGraphBase;
  1083 
  1084 
  1085 
  1086   /// \addtogroup graphs
  1087   /// @{
  1088 
  1089   ///An undirected list graph class.
  1090 
  1091   ///This is a simple and fast undirected graph implementation.
  1092   ///
  1093   ///An important extra feature of this graph implementation is that
  1094   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
  1095   ///
  1096   ///It conforms to the
  1097   ///\ref concepts::UGraph "UGraph concept".
  1098   ///
  1099   ///\sa concepts::UGraph.
  1100   ///
  1101   class ListUGraph : public ExtendedListUGraphBase {
  1102   private:
  1103     ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
  1104 
  1105     ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
  1106     ///
  1107     ListUGraph(const ListUGraph &) :ExtendedListUGraphBase()  {};
  1108     ///\brief Assignment of ListUGraph to another one is \e not allowed.
  1109     ///Use UGraphCopy() instead.
  1110 
  1111     ///Assignment of ListUGraph to another one is \e not allowed.
  1112     ///Use UGraphCopy() instead.
  1113     void operator=(const ListUGraph &) {}
  1114   public:
  1115     /// Constructor
  1116     
  1117     /// Constructor.
  1118     ///
  1119     ListUGraph() {}
  1120 
  1121     typedef ExtendedListUGraphBase Parent;
  1122 
  1123     typedef Parent::OutEdgeIt IncEdgeIt;
  1124 
  1125     /// \brief Add a new node to the graph.
  1126     ///
  1127     /// \return the new node.
  1128     ///
  1129     Node addNode() { return Parent::addNode(); }
  1130 
  1131     /// \brief Add a new edge to the graph.
  1132     ///
  1133     /// Add a new edge to the graph with source node \c s
  1134     /// and target node \c t.
  1135     /// \return the new undirected edge.
  1136     UEdge addEdge(const Node& s, const Node& t) { 
  1137       return Parent::addEdge(s, t); 
  1138     }
  1139     /// \brief Changes the source of \c e to \c n
  1140     ///
  1141     /// Changes the source of \c e to \c n
  1142     ///
  1143     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1144     ///referencing the changed edge remain
  1145     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1146     void changeSource(UEdge e, Node n) { 
  1147       Parent::changeSource(e,n); 
  1148     }    
  1149     /// \brief Changes the target of \c e to \c n
  1150     ///
  1151     /// Changes the target of \c e to \c n
  1152     ///
  1153     /// \note The <tt>EdgeIt</tt>s referencing the changed edge remain
  1154     /// valid. However the other iterators may be invalidated.
  1155     void changeTarget(UEdge e, Node n) { 
  1156       Parent::changeTarget(e,n); 
  1157     }
  1158     /// \brief Changes the source of \c e to \c n
  1159     ///
  1160     /// Changes the source of \c e to \c n. It changes the proper
  1161     /// node of the represented undirected edge.
  1162     ///
  1163     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1164     ///referencing the changed edge remain
  1165     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1166     void changeSource(Edge e, Node n) { 
  1167       if (Parent::direction(e)) {
  1168         Parent::changeSource(e,n);
  1169       } else {
  1170         Parent::changeTarget(e,n);
  1171       } 
  1172     }
  1173     /// \brief Changes the target of \c e to \c n
  1174     ///
  1175     /// Changes the target of \c e to \c n. It changes the proper
  1176     /// node of the represented undirected edge.
  1177     ///
  1178     ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1179     ///referencing the changed edge remain
  1180     ///valid. However <tt>InEdgeIt</tt>s are invalidated.
  1181     void changeTarget(Edge e, Node n) { 
  1182       if (Parent::direction(e)) {
  1183         Parent::changeTarget(e,n);
  1184       } else {
  1185         Parent::changeSource(e,n);
  1186       } 
  1187     }
  1188     /// \brief Contract two nodes.
  1189     ///
  1190     /// This function contracts two nodes.
  1191     ///
  1192     /// Node \p b will be removed but instead of deleting
  1193     /// its neighboring edges, they will be joined to \p a.
  1194     /// The last parameter \p r controls whether to remove loops. \c true
  1195     /// means that loops will be removed.
  1196     ///
  1197     /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
  1198     /// valid.
  1199     void contract(Node a, Node b, bool r = true) {
  1200       for(IncEdgeIt e(*this, b); e!=INVALID;) {
  1201 	IncEdgeIt f = e; ++f;
  1202 	if (r && runningNode(e) == a) {
  1203 	  erase(e);
  1204 	} else if (source(e) == b) {
  1205 	  changeSource(e, a);
  1206 	} else {
  1207 	  changeTarget(e, a);
  1208 	}
  1209 	e = f;
  1210       }
  1211       erase(b);
  1212     }
  1213 
  1214 
  1215     /// \brief Class to make a snapshot of the graph and restore
  1216     /// to it later.
  1217     ///
  1218     /// Class to make a snapshot of the graph and to restore it
  1219     /// later.
  1220     ///
  1221     /// The newly added nodes and undirected edges can be removed
  1222     /// using the restore() function.
  1223     ///
  1224     /// \warning Edge and node deletions cannot be restored. This
  1225     /// events invalidate the snapshot. 
  1226     class Snapshot {
  1227     protected:
  1228 
  1229       typedef Parent::NodeNotifier NodeNotifier;
  1230 
  1231       class NodeObserverProxy : public NodeNotifier::ObserverBase {
  1232       public:
  1233 
  1234         NodeObserverProxy(Snapshot& _snapshot)
  1235           : snapshot(_snapshot) {}
  1236 
  1237         using NodeNotifier::ObserverBase::attach;
  1238         using NodeNotifier::ObserverBase::detach;
  1239         using NodeNotifier::ObserverBase::attached;
  1240         
  1241       protected:
  1242         
  1243         virtual void add(const Node& node) {
  1244           snapshot.addNode(node);
  1245         }
  1246         virtual void add(const std::vector<Node>& nodes) {
  1247           for (int i = nodes.size() - 1; i >= 0; ++i) {
  1248             snapshot.addNode(nodes[i]);
  1249           }
  1250         }
  1251         virtual void erase(const Node& node) {
  1252           snapshot.eraseNode(node);
  1253         }
  1254         virtual void erase(const std::vector<Node>& nodes) {
  1255           for (int i = 0; i < (int)nodes.size(); ++i) {
  1256             snapshot.eraseNode(nodes[i]);
  1257           }
  1258         }
  1259         virtual void build() {
  1260           NodeNotifier* notifier = getNotifier();
  1261           Node node;
  1262           std::vector<Node> nodes;
  1263           for (notifier->first(node); node != INVALID; notifier->next(node)) {
  1264             nodes.push_back(node);
  1265           }
  1266           for (int i = nodes.size() - 1; i >= 0; --i) {
  1267             snapshot.addNode(nodes[i]);
  1268           }
  1269         }
  1270         virtual void clear() {
  1271           NodeNotifier* notifier = getNotifier();
  1272           Node node;
  1273           for (notifier->first(node); node != INVALID; notifier->next(node)) {
  1274             snapshot.eraseNode(node);
  1275           }
  1276         }
  1277 
  1278         Snapshot& snapshot;
  1279       };
  1280 
  1281       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
  1282       public:
  1283 
  1284         UEdgeObserverProxy(Snapshot& _snapshot)
  1285           : snapshot(_snapshot) {}
  1286 
  1287         using UEdgeNotifier::ObserverBase::attach;
  1288         using UEdgeNotifier::ObserverBase::detach;
  1289         using UEdgeNotifier::ObserverBase::attached;
  1290         
  1291       protected:
  1292 
  1293         virtual void add(const UEdge& edge) {
  1294           snapshot.addUEdge(edge);
  1295         }
  1296         virtual void add(const std::vector<UEdge>& edges) {
  1297           for (int i = edges.size() - 1; i >= 0; ++i) {
  1298             snapshot.addUEdge(edges[i]);
  1299           }
  1300         }
  1301         virtual void erase(const UEdge& edge) {
  1302           snapshot.eraseUEdge(edge);
  1303         }
  1304         virtual void erase(const std::vector<UEdge>& edges) {
  1305           for (int i = 0; i < (int)edges.size(); ++i) {
  1306             snapshot.eraseUEdge(edges[i]);
  1307           }
  1308         }
  1309         virtual void build() {
  1310           UEdgeNotifier* notifier = getNotifier();
  1311           UEdge edge;
  1312           std::vector<UEdge> edges;
  1313           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
  1314             edges.push_back(edge);
  1315           }
  1316           for (int i = edges.size() - 1; i >= 0; --i) {
  1317             snapshot.addUEdge(edges[i]);
  1318           }
  1319         }
  1320         virtual void clear() {
  1321           UEdgeNotifier* notifier = getNotifier();
  1322           UEdge edge;
  1323           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
  1324             snapshot.eraseUEdge(edge);
  1325           }
  1326         }
  1327 
  1328         Snapshot& snapshot;
  1329       };
  1330       
  1331       ListUGraph *graph;
  1332 
  1333       NodeObserverProxy node_observer_proxy;
  1334       UEdgeObserverProxy edge_observer_proxy;
  1335 
  1336       std::list<Node> added_nodes;
  1337       std::list<UEdge> added_edges;
  1338 
  1339 
  1340       void addNode(const Node& node) {
  1341         added_nodes.push_front(node);        
  1342       }
  1343       void eraseNode(const Node& node) {
  1344         std::list<Node>::iterator it = 
  1345           std::find(added_nodes.begin(), added_nodes.end(), node);
  1346         if (it == added_nodes.end()) {
  1347           clear();
  1348           edge_observer_proxy.detach();
  1349           throw NodeNotifier::ImmediateDetach();
  1350         } else {
  1351           added_nodes.erase(it);
  1352         }
  1353       }
  1354 
  1355       void addUEdge(const UEdge& edge) {
  1356         added_edges.push_front(edge);        
  1357       }
  1358       void eraseUEdge(const UEdge& edge) {
  1359         std::list<UEdge>::iterator it = 
  1360           std::find(added_edges.begin(), added_edges.end(), edge);
  1361         if (it == added_edges.end()) {
  1362           clear();
  1363           node_observer_proxy.detach();
  1364           throw UEdgeNotifier::ImmediateDetach();
  1365         } else {
  1366           added_edges.erase(it);
  1367         }        
  1368       }
  1369 
  1370       void attach(ListUGraph &_graph) {
  1371 	graph = &_graph;
  1372 	node_observer_proxy.attach(graph->getNotifier(Node()));
  1373         edge_observer_proxy.attach(graph->getNotifier(UEdge()));
  1374       }
  1375             
  1376       void detach() {
  1377 	node_observer_proxy.detach();
  1378 	edge_observer_proxy.detach();
  1379       }
  1380 
  1381       bool attached() const {
  1382         return node_observer_proxy.attached();
  1383       }
  1384 
  1385       void clear() {
  1386         added_nodes.clear();
  1387         added_edges.clear();        
  1388       }
  1389 
  1390     public:
  1391 
  1392       /// \brief Default constructor.
  1393       ///
  1394       /// Default constructor.
  1395       /// To actually make a snapshot you must call save().
  1396       Snapshot() 
  1397         : graph(0), node_observer_proxy(*this), 
  1398           edge_observer_proxy(*this) {}
  1399       
  1400       /// \brief Constructor that immediately makes a snapshot.
  1401       ///      
  1402       /// This constructor immediately makes a snapshot of the graph.
  1403       /// \param _graph The graph we make a snapshot of.
  1404       Snapshot(ListUGraph &_graph) 
  1405         : node_observer_proxy(*this), 
  1406           edge_observer_proxy(*this) {
  1407 	attach(_graph);
  1408       }
  1409       
  1410       /// \brief Make a snapshot.
  1411       ///
  1412       /// Make a snapshot of the graph.
  1413       ///
  1414       /// This function can be called more than once. In case of a repeated
  1415       /// call, the previous snapshot gets lost.
  1416       /// \param _graph The graph we make the snapshot of.
  1417       void save(ListUGraph &_graph) {
  1418         if (attached()) {
  1419           detach();
  1420           clear();
  1421         }
  1422         attach(_graph);
  1423       }
  1424       
  1425       /// \brief Undo the changes until the last snapshot.
  1426       // 
  1427       /// Undo the changes until the last snapshot created by save().
  1428       void restore() {
  1429 	detach();
  1430 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
  1431             it != added_edges.end(); ++it) {
  1432 	  graph->erase(*it);
  1433 	}
  1434 	for(std::list<Node>::iterator it = added_nodes.begin(); 
  1435             it != added_nodes.end(); ++it) {
  1436 	  graph->erase(*it);
  1437 	}
  1438         clear();
  1439       }
  1440 
  1441       /// \brief Gives back true when the snapshot is valid.
  1442       ///
  1443       /// Gives back true when the snapshot is valid.
  1444       bool valid() const {
  1445         return attached();
  1446       }
  1447     };
  1448   };
  1449 
  1450 
  1451   class ListBpUGraphBase {
  1452   public:
  1453 
  1454     class NodeSetError : public LogicError {
  1455     public:
  1456       virtual const char* what() const throw() { 
  1457 	return "lemon::ListBpUGraph::NodeSetError";
  1458       }
  1459     };
  1460 
  1461   protected:
  1462 
  1463     struct NodeT {
  1464       int first_edge, prev, next;
  1465     };
  1466 
  1467     struct UEdgeT {
  1468       int aNode, prev_out, next_out;
  1469       int bNode, prev_in, next_in;
  1470     };
  1471 
  1472     std::vector<NodeT> aNodes;
  1473     std::vector<NodeT> bNodes;
  1474 
  1475     std::vector<UEdgeT> edges;
  1476 
  1477     int first_anode;
  1478     int first_free_anode;
  1479 
  1480     int first_bnode;
  1481     int first_free_bnode;
  1482 
  1483     int first_free_edge;
  1484 
  1485   public:
  1486   
  1487     class Node {
  1488       friend class ListBpUGraphBase;
  1489     protected:
  1490       int id;
  1491 
  1492       explicit Node(int _id) : id(_id) {}
  1493     public:
  1494       Node() {}
  1495       Node(Invalid) { id = -1; }
  1496       bool operator==(const Node i) const {return id==i.id;}
  1497       bool operator!=(const Node i) const {return id!=i.id;}
  1498       bool operator<(const Node i) const {return id<i.id;}
  1499     };
  1500 
  1501     class UEdge {
  1502       friend class ListBpUGraphBase;
  1503     protected:
  1504       int id;
  1505 
  1506       explicit UEdge(int _id) { id = _id;}
  1507     public:
  1508       UEdge() {}
  1509       UEdge (Invalid) { id = -1; }
  1510       bool operator==(const UEdge i) const {return id==i.id;}
  1511       bool operator!=(const UEdge i) const {return id!=i.id;}
  1512       bool operator<(const UEdge i) const {return id<i.id;}
  1513     };
  1514 
  1515     ListBpUGraphBase()
  1516       : first_anode(-1), first_free_anode(-1),
  1517         first_bnode(-1), first_free_bnode(-1),
  1518         first_free_edge(-1) {}
  1519 
  1520     void firstANode(Node& node) const {
  1521       node.id = first_anode != -1 ? (first_anode << 1) : -1;
  1522     }
  1523     void nextANode(Node& node) const {
  1524       node.id = aNodes[node.id >> 1].next;
  1525     }
  1526 
  1527     void firstBNode(Node& node) const {
  1528       node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
  1529     }
  1530     void nextBNode(Node& node) const {
  1531       node.id = bNodes[node.id >> 1].next;
  1532     }
  1533 
  1534     void first(Node& node) const {
  1535       if (first_anode != -1) {
  1536         node.id = (first_anode << 1);
  1537       } else if (first_bnode != -1) {
  1538         node.id = (first_bnode << 1) + 1;
  1539       } else {
  1540         node.id = -1;
  1541       }
  1542     }
  1543     void next(Node& node) const {
  1544       if (aNode(node)) {
  1545         node.id = aNodes[node.id >> 1].next;
  1546         if (node.id == -1) {
  1547           if (first_bnode != -1) {
  1548             node.id = (first_bnode << 1) + 1;
  1549           }
  1550         }
  1551       } else {
  1552         node.id = bNodes[node.id >> 1].next;
  1553       }
  1554     }
  1555   
  1556     void first(UEdge& edge) const {
  1557       int aNodeId = first_anode;
  1558       while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
  1559         aNodeId = aNodes[aNodeId].next != -1 ? 
  1560           aNodes[aNodeId].next >> 1 : -1;
  1561       }
  1562       if (aNodeId != -1) {
  1563         edge.id = aNodes[aNodeId].first_edge;
  1564       } else {
  1565         edge.id = -1;
  1566       }
  1567     }
  1568     void next(UEdge& edge) const {
  1569       int aNodeId = edges[edge.id].aNode >> 1;
  1570       edge.id = edges[edge.id].next_out;
  1571       if (edge.id == -1) {
  1572         aNodeId = aNodes[aNodeId].next != -1 ? 
  1573           aNodes[aNodeId].next >> 1 : -1;
  1574         while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
  1575           aNodeId = aNodes[aNodeId].next != -1 ? 
  1576           aNodes[aNodeId].next >> 1 : -1;
  1577         }
  1578         if (aNodeId != -1) {
  1579           edge.id = aNodes[aNodeId].first_edge;
  1580         } else {
  1581           edge.id = -1;
  1582         }
  1583       }
  1584     }
  1585 
  1586     void firstFromANode(UEdge& edge, const Node& node) const {
  1587       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
  1588       edge.id = aNodes[node.id >> 1].first_edge;
  1589     }
  1590     void nextFromANode(UEdge& edge) const {
  1591       edge.id = edges[edge.id].next_out;
  1592     }
  1593 
  1594     void firstFromBNode(UEdge& edge, const Node& node) const {
  1595       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
  1596       edge.id = bNodes[node.id >> 1].first_edge;
  1597     }
  1598     void nextFromBNode(UEdge& edge) const {
  1599       edge.id = edges[edge.id].next_in;
  1600     }
  1601 
  1602     static int id(const Node& node) {
  1603       return node.id;
  1604     }
  1605     static Node nodeFromId(int id) {
  1606       return Node(id);
  1607     }
  1608     int maxNodeId() const {
  1609       return aNodes.size() > bNodes.size() ?
  1610 	aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
  1611     }
  1612   
  1613     static int id(const UEdge& edge) {
  1614       return edge.id;
  1615     }
  1616     static UEdge uEdgeFromId(int id) {
  1617       return UEdge(id);
  1618     }
  1619     int maxUEdgeId() const {
  1620       return edges.size();
  1621     }
  1622   
  1623     static int aNodeId(const Node& node) {
  1624       return node.id >> 1;
  1625     }
  1626     static Node nodeFromANodeId(int id) {
  1627       return Node(id << 1);
  1628     }
  1629     int maxANodeId() const {
  1630       return aNodes.size();
  1631     }
  1632 
  1633     static int bNodeId(const Node& node) {
  1634       return node.id >> 1;
  1635     }
  1636     static Node nodeFromBNodeId(int id) {
  1637       return Node((id << 1) + 1);
  1638     }
  1639     int maxBNodeId() const {
  1640       return bNodes.size();
  1641     }
  1642 
  1643     Node aNode(const UEdge& edge) const {
  1644       return Node(edges[edge.id].aNode);
  1645     }
  1646     Node bNode(const UEdge& edge) const {
  1647       return Node(edges[edge.id].bNode);
  1648     }
  1649 
  1650     static bool aNode(const Node& node) {
  1651       return (node.id & 1) == 0;
  1652     }
  1653 
  1654     static bool bNode(const Node& node) {
  1655       return (node.id & 1) == 1;
  1656     }
  1657 
  1658     Node addANode() {
  1659       int aNodeId;
  1660       if (first_free_anode == -1) {
  1661         aNodeId = aNodes.size();
  1662         aNodes.push_back(NodeT());
  1663       } else {
  1664         aNodeId = first_free_anode;
  1665         first_free_anode = aNodes[first_free_anode].next;
  1666       }
  1667       if (first_anode != -1) {
  1668         aNodes[aNodeId].next = first_anode << 1;
  1669         aNodes[first_anode].prev = aNodeId << 1;
  1670       } else {
  1671         aNodes[aNodeId].next = -1;
  1672       }
  1673       aNodes[aNodeId].prev = -1;
  1674       first_anode = aNodeId;
  1675       aNodes[aNodeId].first_edge = -1;
  1676       return Node(aNodeId << 1);
  1677     }
  1678 
  1679     Node addBNode() {
  1680       int bNodeId;
  1681       if (first_free_bnode == -1) {
  1682         bNodeId = bNodes.size();
  1683         bNodes.push_back(NodeT());
  1684       } else {
  1685         bNodeId = first_free_bnode;
  1686         first_free_bnode = bNodes[first_free_bnode].next;
  1687       }
  1688       if (first_bnode != -1) {
  1689         bNodes[bNodeId].next = (first_bnode << 1) + 1;
  1690         bNodes[first_bnode].prev = (bNodeId << 1) + 1;
  1691       } else {
  1692         bNodes[bNodeId].next = -1;
  1693       }
  1694       bNodes[bNodeId].prev = -1;
  1695       first_bnode = bNodeId;
  1696       bNodes[bNodeId].first_edge = -1;
  1697       return Node((bNodeId << 1) + 1);
  1698     }
  1699 
  1700     UEdge addEdge(const Node& source, const Node& target) {
  1701       LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
  1702       int edgeId;
  1703       if (first_free_edge != -1) {
  1704         edgeId = first_free_edge;
  1705         first_free_edge = edges[edgeId].next_out;
  1706       } else {
  1707         edgeId = edges.size();
  1708         edges.push_back(UEdgeT());
  1709       }
  1710       if ((source.id & 1) == 0) {
  1711 	edges[edgeId].aNode = source.id;
  1712 	edges[edgeId].bNode = target.id;
  1713       } else {
  1714 	edges[edgeId].aNode = target.id;
  1715 	edges[edgeId].bNode = source.id;
  1716       }
  1717       edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
  1718       edges[edgeId].prev_out = -1;
  1719       if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
  1720         edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
  1721       }
  1722       aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
  1723       edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
  1724       edges[edgeId].prev_in = -1;
  1725       if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
  1726         edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
  1727       }
  1728       bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
  1729       return UEdge(edgeId);
  1730     }
  1731 
  1732     void erase(const Node& node) {
  1733       if (aNode(node)) {
  1734         int aNodeId = node.id >> 1;
  1735         if (aNodes[aNodeId].prev != -1) {
  1736           aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
  1737         } else {
  1738           first_anode = 
  1739             aNodes[aNodeId].next != -1 ? aNodes[aNodeId].next >> 1 : -1;
  1740         }
  1741         if (aNodes[aNodeId].next != -1) {
  1742           aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
  1743         }
  1744         aNodes[aNodeId].next = first_free_anode;
  1745         first_free_anode = aNodeId;
  1746       } else {
  1747         int bNodeId = node.id >> 1;
  1748         if (bNodes[bNodeId].prev != -1) {
  1749           bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
  1750         } else {
  1751           first_bnode = 
  1752             bNodes[bNodeId].next != -1 ? bNodes[bNodeId].next >> 1 : -1;
  1753         }
  1754         if (bNodes[bNodeId].next != -1) {
  1755           bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
  1756         }
  1757         bNodes[bNodeId].next = first_free_bnode;
  1758         first_free_bnode = bNodeId;
  1759       }
  1760     }
  1761 
  1762     void erase(const UEdge& edge) {
  1763 
  1764       if (edges[edge.id].prev_out != -1) {
  1765         edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
  1766       } else {
  1767         aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
  1768       }
  1769       if (edges[edge.id].next_out != -1) {
  1770         edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
  1771       }
  1772 
  1773       if (edges[edge.id].prev_in != -1) {
  1774         edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
  1775       } else {
  1776         bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
  1777       }
  1778       if (edges[edge.id].next_in != -1) {
  1779         edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
  1780       }
  1781 
  1782       edges[edge.id].next_out = first_free_edge;
  1783       first_free_edge = edge.id;
  1784     }
  1785  
  1786     void clear() {
  1787       aNodes.clear();
  1788       bNodes.clear();
  1789       edges.clear();
  1790       first_anode = -1;
  1791       first_free_anode = -1;
  1792       first_bnode = -1;
  1793       first_free_bnode = -1;
  1794       first_free_edge = -1;
  1795     }
  1796 
  1797     void changeANode(const UEdge& edge, const Node& node) {
  1798       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
  1799       if (edges[edge.id].prev_out != -1) {
  1800         edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
  1801       } else {
  1802         aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
  1803       }
  1804       if (edges[edge.id].next_out != -1) {
  1805         edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;  
  1806       }
  1807       if (aNodes[node.id >> 1].first_edge != -1) {
  1808         edges[aNodes[node.id >> 1].first_edge].prev_out = edge.id;
  1809       }
  1810       edges[edge.id].prev_out = -1;
  1811       edges[edge.id].next_out = aNodes[node.id >> 1].first_edge;
  1812       aNodes[node.id >> 1].first_edge = edge.id;
  1813       edges[edge.id].aNode = node.id;
  1814     } 
  1815 
  1816     void changeBNode(const UEdge& edge, const Node& node) {
  1817       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
  1818       if (edges[edge.id].prev_in != -1) {
  1819         edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
  1820       } else {
  1821         bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
  1822       }
  1823       if (edges[edge.id].next_in != -1) {
  1824         edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;  
  1825       }
  1826       if (bNodes[node.id >> 1].first_edge != -1) {
  1827         edges[bNodes[node.id >> 1].first_edge].prev_in = edge.id;
  1828       }
  1829       edges[edge.id].prev_in = -1;
  1830       edges[edge.id].next_in = bNodes[node.id >> 1].first_edge;
  1831       bNodes[node.id >> 1].first_edge = edge.id;
  1832       edges[edge.id].bNode = node.id;
  1833     } 
  1834 
  1835   };
  1836 
  1837 
  1838   typedef BpUGraphExtender<BidirBpUGraphExtender<ListBpUGraphBase> > 
  1839   ExtendedListBpUGraphBase;
  1840 
  1841   /// \ingroup graphs
  1842   ///
  1843   /// \brief A smart bipartite undirected graph class.
  1844   ///
  1845   /// This is a bipartite undirected graph implementation.
  1846   /// It is conforms to the \ref concepts::BpUGraph "BpUGraph concept".
  1847   ///
  1848   ///An important extra feature of this graph implementation is that
  1849   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
  1850   ///
  1851   /// \sa concepts::BpUGraph.
  1852   ///
  1853   class ListBpUGraph : public ExtendedListBpUGraphBase {
  1854     /// \brief ListBpUGraph is \e not copy constructible.
  1855     ///
  1856     ///ListBpUGraph is \e not copy constructible.
  1857     ListBpUGraph(const ListBpUGraph &) :ExtendedListBpUGraphBase()  {};
  1858     /// \brief Assignment of ListBpUGraph to another one is \e not
  1859     /// allowed.
  1860     ///
  1861     /// Assignment of ListBpUGraph to another one is \e not allowed.
  1862     void operator=(const ListBpUGraph &) {}
  1863   public:
  1864     /// \brief Constructor
  1865     ///    
  1866     /// Constructor.
  1867     ///
  1868     ListBpUGraph() {}
  1869 
  1870     typedef ExtendedListBpUGraphBase Parent;
  1871     /// \brief Add a new ANode to the graph.
  1872     ///
  1873     /// \return the new node.
  1874     ///
  1875     Node addANode() { return Parent::addANode(); }
  1876 
  1877     /// \brief Add a new BNode to the graph.
  1878     ///
  1879     /// \return the new node.
  1880     ///
  1881     Node addBNode() { return Parent::addBNode(); }
  1882 
  1883     /// \brief Add a new edge to the graph.
  1884     ///
  1885     /// Add a new edge to the graph with an ANode and a BNode.
  1886     /// \return the new undirected edge.
  1887     UEdge addEdge(const Node& s, const Node& t) { 
  1888       return Parent::addEdge(s, t); 
  1889     }
  1890 
  1891     /// \brief Changes the ANode of \c e to \c n
  1892     ///
  1893     /// Changes the ANode of \c e to \c n
  1894     ///
  1895     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
  1896     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
  1897     ///invalidated.
  1898     void changeANode(UEdge e, Node n) { 
  1899       Parent::changeANode(e,n); 
  1900     }
  1901 
  1902     /// \brief Changes the BNode of \c e to \c n
  1903     ///
  1904     /// Changes the BNode of \c e to \c n
  1905     ///
  1906     /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1907     /// referencing the changed edge remain
  1908     /// valid. However <tt>InEdgeIt</tt>s are invalidated.
  1909     void changeBNode(UEdge e, Node n) { 
  1910       Parent::changeBNode(e,n); 
  1911     }
  1912 
  1913     /// \brief Changes the source(ANode) of \c e to \c n
  1914     ///
  1915     /// Changes the source(ANode) of \c e to \c n
  1916     ///
  1917     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
  1918     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
  1919     ///invalidated.
  1920     void changeSource(UEdge e, Node n) { 
  1921       Parent::changeANode(e,n); 
  1922     }
  1923 
  1924     /// \brief Changes the target(BNode) of \c e to \c n
  1925     ///
  1926     /// Changes the target(BNode) of \c e to \c n
  1927     ///
  1928     /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1929     /// referencing the changed edge remain
  1930     /// valid. However <tt>InEdgeIt</tt>s are invalidated.
  1931     void changeTarget(UEdge e, Node n) { 
  1932       Parent::changeBNode(e,n); 
  1933     }
  1934 
  1935     /// \brief Changes the source of \c e to \c n
  1936     ///
  1937     /// Changes the source of \c e to \c n. It changes the proper
  1938     /// node of the represented undirected edge.
  1939     ///
  1940     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1941     ///referencing the changed edge remain
  1942     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1943     void changeSource(Edge e, Node n) { 
  1944       if (Parent::direction(e)) {
  1945         Parent::changeANode(e,n);
  1946       } else {
  1947         Parent::changeBNode(e,n);
  1948       } 
  1949     }
  1950     /// \brief Changes the target of \c e to \c n
  1951     ///
  1952     /// Changes the target of \c e to \c n. It changes the proper
  1953     /// node of the represented undirected edge.
  1954     ///
  1955     ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1956     ///referencing the changed edge remain
  1957     ///valid. However <tt>InEdgeIt</tt>s are invalidated.
  1958     void changeTarget(Edge e, Node n) { 
  1959       if (Parent::direction(e)) {
  1960         Parent::changeBNode(e,n);
  1961       } else {
  1962         Parent::changeANode(e,n);
  1963       } 
  1964     }
  1965     /// \brief Contract two nodes.
  1966     ///
  1967     /// This function contracts two nodes.
  1968     ///
  1969     /// Node \p b will be removed but instead of deleting its
  1970     /// neighboring edges, they will be joined to \p a.  The two nodes
  1971     /// should be from the same nodeset, of course.
  1972     ///
  1973     /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
  1974     /// valid.
  1975     void contract(const Node& a, const Node& b) {
  1976       LEMON_ASSERT(Parent::aNode(a) == Parent::aNode(b), NodeSetError());
  1977       if (Parent::aNode(a)) {
  1978         for (IncEdgeIt e(*this, b); e!=INVALID;) {
  1979           IncEdgeIt f = e; ++f;
  1980           changeSource(e, a);
  1981           e = f;
  1982         }
  1983       } else {
  1984         for (IncEdgeIt e(*this, b); e!=INVALID;) {
  1985           IncEdgeIt f = e; ++f;
  1986           changeTarget(e, a);
  1987           e = f;
  1988         }
  1989       }
  1990       erase(b);
  1991     }
  1992 
  1993     /// \brief Class to make a snapshot of the graph and restore
  1994     /// to it later.
  1995     ///
  1996     /// Class to make a snapshot of the graph and to restore it
  1997     /// later.
  1998     ///
  1999     /// The newly added nodes and undirected edges can be removed
  2000     /// using the restore() function.
  2001     ///
  2002     /// \warning Edge and node deletions cannot be restored. This
  2003     /// events invalidate the snapshot. 
  2004     class Snapshot {
  2005     protected:
  2006 
  2007       typedef Parent::NodeNotifier NodeNotifier;
  2008 
  2009       class NodeObserverProxy : public NodeNotifier::ObserverBase {
  2010       public:
  2011 
  2012         NodeObserverProxy(Snapshot& _snapshot)
  2013           : snapshot(_snapshot) {}
  2014 
  2015         using NodeNotifier::ObserverBase::attach;
  2016         using NodeNotifier::ObserverBase::detach;
  2017         using NodeNotifier::ObserverBase::attached;
  2018         
  2019       protected:
  2020         
  2021         virtual void add(const Node& node) {
  2022           snapshot.addNode(node);
  2023         }
  2024         virtual void add(const std::vector<Node>& nodes) {
  2025           for (int i = nodes.size() - 1; i >= 0; ++i) {
  2026             snapshot.addNode(nodes[i]);
  2027           }
  2028         }
  2029         virtual void erase(const Node& node) {
  2030           snapshot.eraseNode(node);
  2031         }
  2032         virtual void erase(const std::vector<Node>& nodes) {
  2033           for (int i = 0; i < (int)nodes.size(); ++i) {
  2034             snapshot.eraseNode(nodes[i]);
  2035           }
  2036         }
  2037         virtual void build() {
  2038           NodeNotifier* notifier = getNotifier();
  2039           Node node;
  2040           std::vector<Node> nodes;
  2041           for (notifier->first(node); node != INVALID; notifier->next(node)) {
  2042             nodes.push_back(node);
  2043           }
  2044           for (int i = nodes.size() - 1; i >= 0; --i) {
  2045             snapshot.addNode(nodes[i]);
  2046           }
  2047         }
  2048         virtual void clear() {
  2049           NodeNotifier* notifier = getNotifier();
  2050           Node node;
  2051           for (notifier->first(node); node != INVALID; notifier->next(node)) {
  2052             snapshot.eraseNode(node);
  2053           }
  2054         }
  2055 
  2056         Snapshot& snapshot;
  2057       };
  2058 
  2059       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
  2060       public:
  2061 
  2062         UEdgeObserverProxy(Snapshot& _snapshot)
  2063           : snapshot(_snapshot) {}
  2064 
  2065         using UEdgeNotifier::ObserverBase::attach;
  2066         using UEdgeNotifier::ObserverBase::detach;
  2067         using UEdgeNotifier::ObserverBase::attached;
  2068         
  2069       protected:
  2070 
  2071         virtual void add(const UEdge& edge) {
  2072           snapshot.addUEdge(edge);
  2073         }
  2074         virtual void add(const std::vector<UEdge>& edges) {
  2075           for (int i = edges.size() - 1; i >= 0; ++i) {
  2076             snapshot.addUEdge(edges[i]);
  2077           }
  2078         }
  2079         virtual void erase(const UEdge& edge) {
  2080           snapshot.eraseUEdge(edge);
  2081         }
  2082         virtual void erase(const std::vector<UEdge>& edges) {
  2083           for (int i = 0; i < (int)edges.size(); ++i) {
  2084             snapshot.eraseUEdge(edges[i]);
  2085           }
  2086         }
  2087         virtual void build() {
  2088           UEdgeNotifier* notifier = getNotifier();
  2089           UEdge edge;
  2090           std::vector<UEdge> edges;
  2091           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
  2092             edges.push_back(edge);
  2093           }
  2094           for (int i = edges.size() - 1; i >= 0; --i) {
  2095             snapshot.addUEdge(edges[i]);
  2096           }
  2097         }
  2098         virtual void clear() {
  2099           UEdgeNotifier* notifier = getNotifier();
  2100           UEdge edge;
  2101           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
  2102             snapshot.eraseUEdge(edge);
  2103           }
  2104         }
  2105 
  2106         Snapshot& snapshot;
  2107       };
  2108       
  2109       ListBpUGraph *graph;
  2110 
  2111       NodeObserverProxy node_observer_proxy;
  2112       UEdgeObserverProxy edge_observer_proxy;
  2113 
  2114       std::list<Node> added_nodes;
  2115       std::list<UEdge> added_edges;
  2116 
  2117 
  2118       void addNode(const Node& node) {
  2119         added_nodes.push_front(node);        
  2120       }
  2121       void eraseNode(const Node& node) {
  2122         std::list<Node>::iterator it = 
  2123           std::find(added_nodes.begin(), added_nodes.end(), node);
  2124         if (it == added_nodes.end()) {
  2125           clear();
  2126           edge_observer_proxy.detach();
  2127           throw NodeNotifier::ImmediateDetach();
  2128         } else {
  2129           added_nodes.erase(it);
  2130         }
  2131       }
  2132 
  2133       void addUEdge(const UEdge& edge) {
  2134         added_edges.push_front(edge);        
  2135       }
  2136       void eraseUEdge(const UEdge& edge) {
  2137         std::list<UEdge>::iterator it = 
  2138           std::find(added_edges.begin(), added_edges.end(), edge);
  2139         if (it == added_edges.end()) {
  2140           clear();
  2141           node_observer_proxy.detach();
  2142           throw UEdgeNotifier::ImmediateDetach();
  2143         } else {
  2144           added_edges.erase(it);
  2145         }        
  2146       }
  2147 
  2148       void attach(ListBpUGraph &_graph) {
  2149 	graph = &_graph;
  2150 	node_observer_proxy.attach(graph->getNotifier(Node()));
  2151         edge_observer_proxy.attach(graph->getNotifier(UEdge()));
  2152       }
  2153             
  2154       void detach() {
  2155 	node_observer_proxy.detach();
  2156 	edge_observer_proxy.detach();
  2157       }
  2158 
  2159       bool attached() const {
  2160         return node_observer_proxy.attached();
  2161       }
  2162 
  2163       void clear() {
  2164         added_nodes.clear();
  2165         added_edges.clear();        
  2166       }
  2167 
  2168     public:
  2169 
  2170       /// \brief Default constructor.
  2171       ///
  2172       /// Default constructor.
  2173       /// To actually make a snapshot you must call save().
  2174       Snapshot() 
  2175         : graph(0), node_observer_proxy(*this), 
  2176           edge_observer_proxy(*this) {}
  2177       
  2178       /// \brief Constructor that immediately makes a snapshot.
  2179       ///      
  2180       /// This constructor immediately makes a snapshot of the graph.
  2181       /// \param _graph The graph we make a snapshot of.
  2182       Snapshot(ListBpUGraph &_graph) 
  2183         : node_observer_proxy(*this), 
  2184           edge_observer_proxy(*this) {
  2185 	attach(_graph);
  2186       }
  2187       
  2188       /// \brief Make a snapshot.
  2189       ///
  2190       /// Make a snapshot of the graph.
  2191       ///
  2192       /// This function can be called more than once. In case of a repeated
  2193       /// call, the previous snapshot gets lost.
  2194       /// \param _graph The graph we make the snapshot of.
  2195       void save(ListBpUGraph &_graph) {
  2196         if (attached()) {
  2197           detach();
  2198           clear();
  2199         }
  2200         attach(_graph);
  2201       }
  2202       
  2203       /// \brief Undo the changes until the last snapshot.
  2204       // 
  2205       /// Undo the changes until the last snapshot created by save().
  2206       void restore() {
  2207 	detach();
  2208 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
  2209             it != added_edges.end(); ++it) {
  2210 	  graph->erase(*it);
  2211 	}
  2212 	for(std::list<Node>::iterator it = added_nodes.begin(); 
  2213             it != added_nodes.end(); ++it) {
  2214 	  graph->erase(*it);
  2215 	}
  2216         clear();
  2217       }
  2218 
  2219       /// \brief Gives back true when the snapshot is valid.
  2220       ///
  2221       /// Gives back true when the snapshot is valid.
  2222       bool valid() const {
  2223         return attached();
  2224       }
  2225     };
  2226   };
  2227 
  2228   
  2229   /// @}  
  2230 } //namespace lemon
  2231   
  2232 
  2233 #endif