lemon/list_graph.h
author deba
Thu, 01 Mar 2007 16:47:23 +0000
changeset 2381 0248790c66ea
parent 2343 21587bc5922b
child 2386 81b47fc5c444
permissions -rw-r--r--
Bug fix
     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 = notifier();
   531           Node node;
   532           std::vector<Node> nodes;
   533           for (_notifier->first(node); node != INVALID; 
   534                _notifier->next(node)) {
   535             nodes.push_back(node);
   536           }
   537           for (int i = nodes.size() - 1; i >= 0; --i) {
   538             snapshot.addNode(nodes[i]);
   539           }
   540         }
   541         virtual void clear() {
   542           NodeNotifier* _notifier = notifier();
   543           Node node;
   544           for (_notifier->first(node); node != INVALID; 
   545                _notifier->next(node)) {
   546             snapshot.eraseNode(node);
   547           }
   548         }
   549 
   550         Snapshot& snapshot;
   551       };
   552 
   553       class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
   554       public:
   555 
   556         EdgeObserverProxy(Snapshot& _snapshot)
   557           : snapshot(_snapshot) {}
   558 
   559         using EdgeNotifier::ObserverBase::attach;
   560         using EdgeNotifier::ObserverBase::detach;
   561         using EdgeNotifier::ObserverBase::attached;
   562         
   563       protected:
   564 
   565         virtual void add(const Edge& edge) {
   566           snapshot.addEdge(edge);
   567         }
   568         virtual void add(const std::vector<Edge>& edges) {
   569           for (int i = edges.size() - 1; i >= 0; ++i) {
   570             snapshot.addEdge(edges[i]);
   571           }
   572         }
   573         virtual void erase(const Edge& edge) {
   574           snapshot.eraseEdge(edge);
   575         }
   576         virtual void erase(const std::vector<Edge>& edges) {
   577           for (int i = 0; i < (int)edges.size(); ++i) {
   578             snapshot.eraseEdge(edges[i]);
   579           }
   580         }
   581         virtual void build() {
   582           EdgeNotifier* _notifier = notifier();
   583           Edge edge;
   584           std::vector<Edge> edges;
   585           for (_notifier->first(edge); edge != INVALID; 
   586                _notifier->next(edge)) {
   587             edges.push_back(edge);
   588           }
   589           for (int i = edges.size() - 1; i >= 0; --i) {
   590             snapshot.addEdge(edges[i]);
   591           }
   592         }
   593         virtual void clear() {
   594           EdgeNotifier* _notifier = notifier();
   595           Edge edge;
   596           for (_notifier->first(edge); edge != INVALID; _notifier->next(edge)) {
   597             snapshot.eraseEdge(edge);
   598           }
   599         }
   600 
   601         Snapshot& snapshot;
   602       };
   603       
   604       ListGraph *graph;
   605 
   606       NodeObserverProxy node_observer_proxy;
   607       EdgeObserverProxy edge_observer_proxy;
   608 
   609       std::list<Node> added_nodes;
   610       std::list<Edge> added_edges;
   611 
   612 
   613       void addNode(const Node& node) {
   614         added_nodes.push_front(node);        
   615       }
   616       void eraseNode(const Node& node) {
   617         std::list<Node>::iterator it = 
   618           std::find(added_nodes.begin(), added_nodes.end(), node);
   619         if (it == added_nodes.end()) {
   620           clear();
   621           edge_observer_proxy.detach();
   622           throw NodeNotifier::ImmediateDetach();
   623         } else {
   624           added_nodes.erase(it);
   625         }
   626       }
   627 
   628       void addEdge(const Edge& edge) {
   629         added_edges.push_front(edge);        
   630       }
   631       void eraseEdge(const Edge& edge) {
   632         std::list<Edge>::iterator it = 
   633           std::find(added_edges.begin(), added_edges.end(), edge);
   634         if (it == added_edges.end()) {
   635           clear();
   636           node_observer_proxy.detach(); 
   637           throw EdgeNotifier::ImmediateDetach();
   638         } else {
   639           added_edges.erase(it);
   640         }        
   641       }
   642 
   643       void attach(ListGraph &_graph) {
   644 	graph = &_graph;
   645 	node_observer_proxy.attach(graph->notifier(Node()));
   646         edge_observer_proxy.attach(graph->notifier(Edge()));
   647       }
   648             
   649       void detach() {
   650 	node_observer_proxy.detach();
   651 	edge_observer_proxy.detach();
   652       }
   653 
   654       bool attached() const {
   655         return node_observer_proxy.attached();
   656       }
   657 
   658       void clear() {
   659         added_nodes.clear();
   660         added_edges.clear();        
   661       }
   662 
   663     public:
   664 
   665       /// \brief Default constructor.
   666       ///
   667       /// Default constructor.
   668       /// To actually make a snapshot you must call save().
   669       Snapshot() 
   670         : graph(0), node_observer_proxy(*this), 
   671           edge_observer_proxy(*this) {}
   672       
   673       /// \brief Constructor that immediately makes a snapshot.
   674       ///      
   675       /// This constructor immediately makes a snapshot of the graph.
   676       /// \param _graph The graph we make a snapshot of.
   677       Snapshot(ListGraph &_graph) 
   678         : node_observer_proxy(*this), 
   679           edge_observer_proxy(*this) {
   680 	attach(_graph);
   681       }
   682       
   683       /// \brief Make a snapshot.
   684       ///
   685       /// Make a snapshot of the graph.
   686       ///
   687       /// This function can be called more than once. In case of a repeated
   688       /// call, the previous snapshot gets lost.
   689       /// \param _graph The graph we make the snapshot of.
   690       void save(ListGraph &_graph) {
   691         if (attached()) {
   692           detach();
   693           clear();
   694         }
   695         attach(_graph);
   696       }
   697       
   698       /// \brief Undo the changes until the last snapshot.
   699       // 
   700       /// Undo the changes until the last snapshot created by save().
   701       void restore() {
   702 	detach();
   703 	for(std::list<Edge>::iterator it = added_edges.begin(); 
   704             it != added_edges.end(); ++it) {
   705 	  graph->erase(*it);
   706 	}
   707 	for(std::list<Node>::iterator it = added_nodes.begin(); 
   708             it != added_nodes.end(); ++it) {
   709 	  graph->erase(*it);
   710 	}
   711         clear();
   712       }
   713 
   714       /// \brief Gives back true when the snapshot is valid.
   715       ///
   716       /// Gives back true when the snapshot is valid.
   717       bool valid() const {
   718         return attached();
   719       }
   720     };
   721     
   722   };
   723 
   724   ///@}
   725 
   726   class ListUGraphBase {
   727 
   728   protected:
   729 
   730     struct NodeT {
   731       int first_out;
   732       int prev, next;
   733     };
   734  
   735     struct EdgeT {
   736       int target;
   737       int prev_out, next_out;
   738     };
   739 
   740     std::vector<NodeT> nodes;
   741 
   742     int first_node;
   743 
   744     int first_free_node;
   745 
   746     std::vector<EdgeT> edges;
   747 
   748     int first_free_edge;
   749     
   750   public:
   751     
   752     typedef ListUGraphBase Graph;
   753 
   754     class Node;
   755     class Edge;
   756     class UEdge;
   757     
   758     class Node {
   759       friend class ListUGraphBase;
   760     protected:
   761 
   762       int id;
   763       explicit Node(int pid) { id = pid;}
   764 
   765     public:
   766       Node() {}
   767       Node (Invalid) { id = -1; }
   768       bool operator==(const Node& node) const {return id == node.id;}
   769       bool operator!=(const Node& node) const {return id != node.id;}
   770       bool operator<(const Node& node) const {return id < node.id;}
   771     };
   772 
   773     class UEdge {
   774       friend class ListUGraphBase;
   775     protected:
   776 
   777       int id;
   778       explicit UEdge(int pid) { id = pid;}
   779 
   780     public:
   781       UEdge() {}
   782       UEdge (Invalid) { id = -1; }
   783       bool operator==(const UEdge& edge) const {return id == edge.id;}
   784       bool operator!=(const UEdge& edge) const {return id != edge.id;}
   785       bool operator<(const UEdge& edge) const {return id < edge.id;}
   786     };
   787 
   788     class Edge {
   789       friend class ListUGraphBase;
   790     protected:
   791 
   792       int id;
   793       explicit Edge(int pid) { id = pid;}
   794 
   795     public:
   796       operator UEdge() const { return uEdgeFromId(id / 2); }
   797 
   798       Edge() {}
   799       Edge (Invalid) { id = -1; }
   800       bool operator==(const Edge& edge) const {return id == edge.id;}
   801       bool operator!=(const Edge& edge) const {return id != edge.id;}
   802       bool operator<(const Edge& edge) const {return id < edge.id;}
   803     };
   804 
   805 
   806 
   807     ListUGraphBase()
   808       : nodes(), first_node(-1),
   809 	first_free_node(-1), edges(), first_free_edge(-1) {}
   810 
   811     
   812     int maxNodeId() const { return nodes.size()-1; } 
   813     int maxUEdgeId() const { return edges.size() / 2 - 1; }
   814     int maxEdgeId() const { return edges.size()-1; }
   815 
   816     Node source(Edge e) const { return Node(edges[e.id ^ 1].target); }
   817     Node target(Edge e) const { return Node(edges[e.id].target); }
   818 
   819     Node source(UEdge e) const { return Node(edges[2 * e.id].target); }
   820     Node target(UEdge e) const { return Node(edges[2 * e.id + 1].target); }
   821 
   822     static bool direction(Edge e) {
   823       return (e.id & 1) == 1;
   824     }
   825 
   826     static Edge direct(UEdge e, bool d) {
   827       return Edge(e.id * 2 + (d ? 1 : 0));
   828     }
   829 
   830     void first(Node& node) const { 
   831       node.id = first_node;
   832     }
   833 
   834     void next(Node& node) const {
   835       node.id = nodes[node.id].next;
   836     }
   837 
   838     void first(Edge& e) const { 
   839       int n = first_node;
   840       while (n != -1 && nodes[n].first_out == -1) {
   841         n = nodes[n].next;
   842       }
   843       e.id = (n == -1) ? -1 : nodes[n].first_out;
   844     }
   845 
   846     void next(Edge& e) const {
   847       if (edges[e.id].next_out != -1) {
   848 	e.id = edges[e.id].next_out;
   849       } else {
   850 	int n = nodes[edges[e.id ^ 1].target].next;
   851         while(n != -1 && nodes[n].first_out == -1) {
   852           n = nodes[n].next;
   853         }
   854 	e.id = (n == -1) ? -1 : nodes[n].first_out;
   855       }      
   856     }
   857 
   858     void first(UEdge& e) const { 
   859       int n = first_node;
   860       while (n != -1) {
   861         e.id = nodes[n].first_out;
   862         while ((e.id & 1) != 1) {
   863           e.id = edges[e.id].next_out;
   864         }
   865         if (e.id != -1) {
   866           e.id /= 2;
   867           return;
   868         } 
   869         n = nodes[n].next;
   870       }
   871       e.id = -1;
   872     }
   873 
   874     void next(UEdge& e) const {
   875       int n = edges[e.id * 2].target;
   876       e.id = edges[(e.id * 2) | 1].next_out;
   877       while ((e.id & 1) != 1) {
   878         e.id = edges[e.id].next_out;
   879       }
   880       if (e.id != -1) {
   881         e.id /= 2;
   882         return;
   883       } 
   884       n = nodes[n].next;
   885       while (n != -1) {
   886         e.id = nodes[n].first_out;
   887         while ((e.id & 1) != 1) {
   888           e.id = edges[e.id].next_out;
   889         }
   890         if (e.id != -1) {
   891           e.id /= 2;
   892           return;
   893         } 
   894         n = nodes[n].next;
   895       }
   896       e.id = -1;
   897     }
   898 
   899     void firstOut(Edge &e, const Node& v) const {
   900       e.id = nodes[v.id].first_out;
   901     }
   902     void nextOut(Edge &e) const {
   903       e.id = edges[e.id].next_out;
   904     }
   905 
   906     void firstIn(Edge &e, const Node& v) const {
   907       e.id = ((nodes[v.id].first_out) ^ 1);
   908       if (e.id == -2) e.id = -1;
   909     }
   910     void nextIn(Edge &e) const {
   911       e.id = ((edges[e.id ^ 1].next_out) ^ 1);
   912       if (e.id == -2) e.id = -1;
   913     }
   914 
   915     void firstInc(UEdge &e, bool& d, const Node& v) const {
   916       int de = nodes[v.id].first_out;
   917       if (de != -1 ) {
   918         e.id = de / 2;
   919         d = ((de & 1) == 1);
   920       } else {
   921         e.id = -1;
   922         d = true;
   923       }
   924     }
   925     void nextInc(UEdge &e, bool& d) const {
   926       int de = (edges[(e.id * 2) | (d ? 1 : 0)].next_out);
   927       if (de != -1 ) {
   928         e.id = de / 2;
   929         d = ((de & 1) == 1);
   930       } else {
   931         e.id = -1;
   932         d = true;
   933       }
   934     }
   935     
   936     static int id(Node v) { return v.id; }
   937     static int id(Edge e) { return e.id; }
   938     static int id(UEdge e) { return e.id; }
   939 
   940     static Node nodeFromId(int id) { return Node(id);}
   941     static Edge edgeFromId(int id) { return Edge(id);}
   942     static UEdge uEdgeFromId(int id) { return UEdge(id);}
   943 
   944     Node addNode() {     
   945       int n;
   946       
   947       if(first_free_node==-1) {
   948 	n = nodes.size();
   949 	nodes.push_back(NodeT());
   950       } else {
   951 	n = first_free_node;
   952 	first_free_node = nodes[n].next;
   953       }
   954       
   955       nodes[n].next = first_node;
   956       if (first_node != -1) nodes[first_node].prev = n;
   957       first_node = n;
   958       nodes[n].prev = -1;
   959       
   960       nodes[n].first_out = -1;
   961       
   962       return Node(n);
   963     }
   964     
   965     UEdge addEdge(Node u, Node v) {
   966       int n;      
   967 
   968       if (first_free_edge == -1) {
   969 	n = edges.size();
   970 	edges.push_back(EdgeT());
   971 	edges.push_back(EdgeT());
   972       } else {
   973 	n = first_free_edge;
   974 	first_free_edge = edges[n].next_out;
   975       }
   976       
   977       edges[n].target = u.id;
   978       edges[n | 1].target = v.id;
   979 
   980       edges[n].next_out = nodes[v.id].first_out;
   981       edges[n | 1].next_out = nodes[u.id].first_out;
   982       if (nodes[v.id].first_out != -1) {
   983 	edges[nodes[v.id].first_out].prev_out = n;
   984       }
   985       if (nodes[u.id].first_out != -1) {
   986 	edges[nodes[u.id].first_out].prev_out = (n | 1);
   987       }
   988       
   989       edges[n].prev_out = edges[n | 1].prev_out = -1;
   990 	
   991       nodes[v.id].first_out = n;
   992       nodes[u.id].first_out = (n | 1);
   993 
   994       return UEdge(n / 2);
   995     }
   996     
   997     void erase(const Node& node) {
   998       int n = node.id;
   999       
  1000       if(nodes[n].next != -1) {
  1001 	nodes[nodes[n].next].prev = nodes[n].prev;
  1002       }
  1003       
  1004       if(nodes[n].prev != -1) {
  1005 	nodes[nodes[n].prev].next = nodes[n].next;
  1006       } else {
  1007 	first_node = nodes[n].next;
  1008       }
  1009       
  1010       nodes[n].next = first_free_node;
  1011       first_free_node = n;
  1012 
  1013     }
  1014     
  1015     void erase(const UEdge& edge) {
  1016       int n = edge.id * 2;
  1017       
  1018       if (edges[n].next_out != -1) {
  1019 	edges[edges[n].next_out].prev_out = edges[n].prev_out;
  1020       } 
  1021 
  1022       if (edges[n].prev_out != -1) {
  1023 	edges[edges[n].prev_out].next_out = edges[n].next_out;
  1024       } else {
  1025 	nodes[edges[n | 1].target].first_out = edges[n].next_out;
  1026       }
  1027 
  1028       if (edges[n | 1].next_out != -1) {
  1029 	edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
  1030       } 
  1031 
  1032       if (edges[n | 1].prev_out != -1) {
  1033 	edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
  1034       } else {
  1035 	nodes[edges[n].target].first_out = edges[n | 1].next_out;
  1036       }
  1037       
  1038       edges[n].next_out = first_free_edge;
  1039       first_free_edge = n;      
  1040 
  1041     }
  1042 
  1043     void clear() {
  1044       edges.clear();
  1045       nodes.clear();
  1046       first_node = first_free_node = first_free_edge = -1;
  1047     }
  1048 
  1049   protected:
  1050 
  1051     void changeTarget(UEdge e, Node n) {
  1052       if(edges[2 * e.id].next_out != -1) {
  1053 	edges[edges[2 * e.id].next_out].prev_out = edges[2 * e.id].prev_out;
  1054       }
  1055       if(edges[2 * e.id].prev_out != -1) {
  1056 	edges[edges[2 * e.id].prev_out].next_out = 
  1057           edges[2 * e.id].next_out;
  1058       } else {
  1059         nodes[edges[(2 * e.id) | 1].target].first_out = 
  1060           edges[2 * e.id].next_out;
  1061       }
  1062 
  1063       if (nodes[n.id].first_out != -1) {
  1064 	edges[nodes[n.id].first_out].prev_out = 2 * e.id;
  1065       }
  1066       edges[(2 * e.id) | 1].target = n.id;
  1067       edges[2 * e.id].prev_out = -1;
  1068       edges[2 * e.id].next_out = nodes[n.id].first_out;
  1069       nodes[n.id].first_out = 2 * e.id;
  1070     }
  1071 
  1072     void changeSource(UEdge e, Node n) {
  1073       if(edges[(2 * e.id) | 1].next_out != -1) {
  1074 	edges[edges[(2 * e.id) | 1].next_out].prev_out = 
  1075           edges[(2 * e.id) | 1].prev_out;
  1076       }
  1077       if(edges[(2 * e.id) | 1].prev_out != -1) {
  1078 	edges[edges[(2 * e.id) | 1].prev_out].next_out = 
  1079           edges[(2 * e.id) | 1].next_out;
  1080       } else {
  1081         nodes[edges[2 * e.id].target].first_out = 
  1082           edges[(2 * e.id) | 1].next_out;
  1083       }
  1084 
  1085       if (nodes[n.id].first_out != -1) {
  1086 	edges[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
  1087       }
  1088       edges[2 * e.id].target = n.id;
  1089       edges[(2 * e.id) | 1].prev_out = -1;
  1090       edges[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
  1091       nodes[n.id].first_out = ((2 * e.id) | 1);
  1092     }
  1093 
  1094   };
  1095 
  1096 //   typedef UGraphExtender<UndirGraphExtender<ListGraphBase> > 
  1097 //   ExtendedListUGraphBase;
  1098 
  1099   typedef UGraphExtender<ListUGraphBase> ExtendedListUGraphBase;
  1100 
  1101 
  1102 
  1103   /// \addtogroup graphs
  1104   /// @{
  1105 
  1106   ///An undirected list graph class.
  1107 
  1108   ///This is a simple and fast undirected graph implementation.
  1109   ///
  1110   ///An important extra feature of this graph implementation is that
  1111   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
  1112   ///
  1113   ///It conforms to the
  1114   ///\ref concepts::UGraph "UGraph concept".
  1115   ///
  1116   ///\sa concepts::UGraph.
  1117   ///
  1118   class ListUGraph : public ExtendedListUGraphBase {
  1119   private:
  1120     ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
  1121 
  1122     ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
  1123     ///
  1124     ListUGraph(const ListUGraph &) :ExtendedListUGraphBase()  {};
  1125     ///\brief Assignment of ListUGraph to another one is \e not allowed.
  1126     ///Use UGraphCopy() instead.
  1127 
  1128     ///Assignment of ListUGraph to another one is \e not allowed.
  1129     ///Use UGraphCopy() instead.
  1130     void operator=(const ListUGraph &) {}
  1131   public:
  1132     /// Constructor
  1133     
  1134     /// Constructor.
  1135     ///
  1136     ListUGraph() {}
  1137 
  1138     typedef ExtendedListUGraphBase Parent;
  1139 
  1140     typedef Parent::OutEdgeIt IncEdgeIt;
  1141 
  1142     /// \brief Add a new node to the graph.
  1143     ///
  1144     /// \return the new node.
  1145     ///
  1146     Node addNode() { return Parent::addNode(); }
  1147 
  1148     /// \brief Add a new edge to the graph.
  1149     ///
  1150     /// Add a new edge to the graph with source node \c s
  1151     /// and target node \c t.
  1152     /// \return the new undirected edge.
  1153     UEdge addEdge(const Node& s, const Node& t) { 
  1154       return Parent::addEdge(s, t); 
  1155     }
  1156     /// \brief Changes the source of \c e to \c n
  1157     ///
  1158     /// Changes the source of \c e to \c n
  1159     ///
  1160     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1161     ///referencing the changed edge remain
  1162     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1163     void changeSource(UEdge e, Node n) { 
  1164       Parent::changeSource(e,n); 
  1165     }    
  1166     /// \brief Changes the target of \c e to \c n
  1167     ///
  1168     /// Changes the target of \c e to \c n
  1169     ///
  1170     /// \note The <tt>EdgeIt</tt>s referencing the changed edge remain
  1171     /// valid. However the other iterators may be invalidated.
  1172     void changeTarget(UEdge e, Node n) { 
  1173       Parent::changeTarget(e,n); 
  1174     }
  1175     /// \brief Changes the source of \c e to \c n
  1176     ///
  1177     /// Changes the source of \c e to \c n. It changes the proper
  1178     /// node of the represented undirected edge.
  1179     ///
  1180     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1181     ///referencing the changed edge remain
  1182     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1183     void changeSource(Edge e, Node n) { 
  1184       if (Parent::direction(e)) {
  1185         Parent::changeSource(e,n);
  1186       } else {
  1187         Parent::changeTarget(e,n);
  1188       } 
  1189     }
  1190     /// \brief Changes the target of \c e to \c n
  1191     ///
  1192     /// Changes the target of \c e to \c n. It changes the proper
  1193     /// node of the represented undirected edge.
  1194     ///
  1195     ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1196     ///referencing the changed edge remain
  1197     ///valid. However <tt>InEdgeIt</tt>s are invalidated.
  1198     void changeTarget(Edge e, Node n) { 
  1199       if (Parent::direction(e)) {
  1200         Parent::changeTarget(e,n);
  1201       } else {
  1202         Parent::changeSource(e,n);
  1203       } 
  1204     }
  1205     /// \brief Contract two nodes.
  1206     ///
  1207     /// This function contracts two nodes.
  1208     ///
  1209     /// Node \p b will be removed but instead of deleting
  1210     /// its neighboring edges, they will be joined to \p a.
  1211     /// The last parameter \p r controls whether to remove loops. \c true
  1212     /// means that loops will be removed.
  1213     ///
  1214     /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
  1215     /// valid.
  1216     void contract(Node a, Node b, bool r = true) {
  1217       for(IncEdgeIt e(*this, b); e!=INVALID;) {
  1218 	IncEdgeIt f = e; ++f;
  1219 	if (r && runningNode(e) == a) {
  1220 	  erase(e);
  1221 	} else if (source(e) == b) {
  1222 	  changeSource(e, a);
  1223 	} else {
  1224 	  changeTarget(e, a);
  1225 	}
  1226 	e = f;
  1227       }
  1228       erase(b);
  1229     }
  1230 
  1231 
  1232     /// \brief Class to make a snapshot of the graph and restore
  1233     /// to it later.
  1234     ///
  1235     /// Class to make a snapshot of the graph and to restore it
  1236     /// later.
  1237     ///
  1238     /// The newly added nodes and undirected edges can be removed
  1239     /// using the restore() function.
  1240     ///
  1241     /// \warning Edge and node deletions cannot be restored. This
  1242     /// events invalidate the snapshot. 
  1243     class Snapshot {
  1244     protected:
  1245 
  1246       typedef Parent::NodeNotifier NodeNotifier;
  1247 
  1248       class NodeObserverProxy : public NodeNotifier::ObserverBase {
  1249       public:
  1250 
  1251         NodeObserverProxy(Snapshot& _snapshot)
  1252           : snapshot(_snapshot) {}
  1253 
  1254         using NodeNotifier::ObserverBase::attach;
  1255         using NodeNotifier::ObserverBase::detach;
  1256         using NodeNotifier::ObserverBase::attached;
  1257         
  1258       protected:
  1259         
  1260         virtual void add(const Node& node) {
  1261           snapshot.addNode(node);
  1262         }
  1263         virtual void add(const std::vector<Node>& nodes) {
  1264           for (int i = nodes.size() - 1; i >= 0; ++i) {
  1265             snapshot.addNode(nodes[i]);
  1266           }
  1267         }
  1268         virtual void erase(const Node& node) {
  1269           snapshot.eraseNode(node);
  1270         }
  1271         virtual void erase(const std::vector<Node>& nodes) {
  1272           for (int i = 0; i < (int)nodes.size(); ++i) {
  1273             snapshot.eraseNode(nodes[i]);
  1274           }
  1275         }
  1276         virtual void build() {
  1277           NodeNotifier* _notifier = notifier();
  1278           Node node;
  1279           std::vector<Node> nodes;
  1280           for (_notifier->first(node); node != INVALID; 
  1281                _notifier->next(node)) {
  1282             nodes.push_back(node);
  1283           }
  1284           for (int i = nodes.size() - 1; i >= 0; --i) {
  1285             snapshot.addNode(nodes[i]);
  1286           }
  1287         }
  1288         virtual void clear() {
  1289           NodeNotifier* _notifier = notifier();
  1290           Node node;
  1291           for (_notifier->first(node); node != INVALID; 
  1292                _notifier->next(node)) {
  1293             snapshot.eraseNode(node);
  1294           }
  1295         }
  1296 
  1297         Snapshot& snapshot;
  1298       };
  1299 
  1300       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
  1301       public:
  1302 
  1303         UEdgeObserverProxy(Snapshot& _snapshot)
  1304           : snapshot(_snapshot) {}
  1305 
  1306         using UEdgeNotifier::ObserverBase::attach;
  1307         using UEdgeNotifier::ObserverBase::detach;
  1308         using UEdgeNotifier::ObserverBase::attached;
  1309         
  1310       protected:
  1311 
  1312         virtual void add(const UEdge& edge) {
  1313           snapshot.addUEdge(edge);
  1314         }
  1315         virtual void add(const std::vector<UEdge>& edges) {
  1316           for (int i = edges.size() - 1; i >= 0; ++i) {
  1317             snapshot.addUEdge(edges[i]);
  1318           }
  1319         }
  1320         virtual void erase(const UEdge& edge) {
  1321           snapshot.eraseUEdge(edge);
  1322         }
  1323         virtual void erase(const std::vector<UEdge>& edges) {
  1324           for (int i = 0; i < (int)edges.size(); ++i) {
  1325             snapshot.eraseUEdge(edges[i]);
  1326           }
  1327         }
  1328         virtual void build() {
  1329           UEdgeNotifier* _notifier = notifier();
  1330           UEdge edge;
  1331           std::vector<UEdge> edges;
  1332           for (_notifier->first(edge); edge != INVALID; 
  1333                _notifier->next(edge)) {
  1334             edges.push_back(edge);
  1335           }
  1336           for (int i = edges.size() - 1; i >= 0; --i) {
  1337             snapshot.addUEdge(edges[i]);
  1338           }
  1339         }
  1340         virtual void clear() {
  1341           UEdgeNotifier* _notifier = notifier();
  1342           UEdge edge;
  1343           for (_notifier->first(edge); edge != INVALID; 
  1344                _notifier->next(edge)) {
  1345             snapshot.eraseUEdge(edge);
  1346           }
  1347         }
  1348 
  1349         Snapshot& snapshot;
  1350       };
  1351       
  1352       ListUGraph *graph;
  1353 
  1354       NodeObserverProxy node_observer_proxy;
  1355       UEdgeObserverProxy edge_observer_proxy;
  1356 
  1357       std::list<Node> added_nodes;
  1358       std::list<UEdge> added_edges;
  1359 
  1360 
  1361       void addNode(const Node& node) {
  1362         added_nodes.push_front(node);        
  1363       }
  1364       void eraseNode(const Node& node) {
  1365         std::list<Node>::iterator it = 
  1366           std::find(added_nodes.begin(), added_nodes.end(), node);
  1367         if (it == added_nodes.end()) {
  1368           clear();
  1369           edge_observer_proxy.detach();
  1370           throw NodeNotifier::ImmediateDetach();
  1371         } else {
  1372           added_nodes.erase(it);
  1373         }
  1374       }
  1375 
  1376       void addUEdge(const UEdge& edge) {
  1377         added_edges.push_front(edge);        
  1378       }
  1379       void eraseUEdge(const UEdge& edge) {
  1380         std::list<UEdge>::iterator it = 
  1381           std::find(added_edges.begin(), added_edges.end(), edge);
  1382         if (it == added_edges.end()) {
  1383           clear();
  1384           node_observer_proxy.detach();
  1385           throw UEdgeNotifier::ImmediateDetach();
  1386         } else {
  1387           added_edges.erase(it);
  1388         }        
  1389       }
  1390 
  1391       void attach(ListUGraph &_graph) {
  1392 	graph = &_graph;
  1393 	node_observer_proxy.attach(graph->notifier(Node()));
  1394         edge_observer_proxy.attach(graph->notifier(UEdge()));
  1395       }
  1396             
  1397       void detach() {
  1398 	node_observer_proxy.detach();
  1399 	edge_observer_proxy.detach();
  1400       }
  1401 
  1402       bool attached() const {
  1403         return node_observer_proxy.attached();
  1404       }
  1405 
  1406       void clear() {
  1407         added_nodes.clear();
  1408         added_edges.clear();        
  1409       }
  1410 
  1411     public:
  1412 
  1413       /// \brief Default constructor.
  1414       ///
  1415       /// Default constructor.
  1416       /// To actually make a snapshot you must call save().
  1417       Snapshot() 
  1418         : graph(0), node_observer_proxy(*this), 
  1419           edge_observer_proxy(*this) {}
  1420       
  1421       /// \brief Constructor that immediately makes a snapshot.
  1422       ///      
  1423       /// This constructor immediately makes a snapshot of the graph.
  1424       /// \param _graph The graph we make a snapshot of.
  1425       Snapshot(ListUGraph &_graph) 
  1426         : node_observer_proxy(*this), 
  1427           edge_observer_proxy(*this) {
  1428 	attach(_graph);
  1429       }
  1430       
  1431       /// \brief Make a snapshot.
  1432       ///
  1433       /// Make a snapshot of the graph.
  1434       ///
  1435       /// This function can be called more than once. In case of a repeated
  1436       /// call, the previous snapshot gets lost.
  1437       /// \param _graph The graph we make the snapshot of.
  1438       void save(ListUGraph &_graph) {
  1439         if (attached()) {
  1440           detach();
  1441           clear();
  1442         }
  1443         attach(_graph);
  1444       }
  1445       
  1446       /// \brief Undo the changes until the last snapshot.
  1447       // 
  1448       /// Undo the changes until the last snapshot created by save().
  1449       void restore() {
  1450 	detach();
  1451 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
  1452             it != added_edges.end(); ++it) {
  1453 	  graph->erase(*it);
  1454 	}
  1455 	for(std::list<Node>::iterator it = added_nodes.begin(); 
  1456             it != added_nodes.end(); ++it) {
  1457 	  graph->erase(*it);
  1458 	}
  1459         clear();
  1460       }
  1461 
  1462       /// \brief Gives back true when the snapshot is valid.
  1463       ///
  1464       /// Gives back true when the snapshot is valid.
  1465       bool valid() const {
  1466         return attached();
  1467       }
  1468     };
  1469   };
  1470 
  1471 
  1472   class ListBpUGraphBase {
  1473   public:
  1474 
  1475     class NodeSetError : public LogicError {
  1476     public:
  1477       virtual const char* what() const throw() { 
  1478 	return "lemon::ListBpUGraph::NodeSetError";
  1479       }
  1480     };
  1481 
  1482   protected:
  1483 
  1484     struct NodeT {
  1485       int first_edge, prev, next;
  1486     };
  1487 
  1488     struct UEdgeT {
  1489       int aNode, prev_out, next_out;
  1490       int bNode, prev_in, next_in;
  1491     };
  1492 
  1493     std::vector<NodeT> aNodes;
  1494     std::vector<NodeT> bNodes;
  1495 
  1496     std::vector<UEdgeT> edges;
  1497 
  1498     int first_anode;
  1499     int first_free_anode;
  1500 
  1501     int first_bnode;
  1502     int first_free_bnode;
  1503 
  1504     int first_free_edge;
  1505 
  1506   public:
  1507   
  1508     class Node {
  1509       friend class ListBpUGraphBase;
  1510     protected:
  1511       int id;
  1512 
  1513       explicit Node(int _id) : id(_id) {}
  1514     public:
  1515       Node() {}
  1516       Node(Invalid) { id = -1; }
  1517       bool operator==(const Node i) const {return id==i.id;}
  1518       bool operator!=(const Node i) const {return id!=i.id;}
  1519       bool operator<(const Node i) const {return id<i.id;}
  1520     };
  1521 
  1522     class UEdge {
  1523       friend class ListBpUGraphBase;
  1524     protected:
  1525       int id;
  1526 
  1527       explicit UEdge(int _id) { id = _id;}
  1528     public:
  1529       UEdge() {}
  1530       UEdge (Invalid) { id = -1; }
  1531       bool operator==(const UEdge i) const {return id==i.id;}
  1532       bool operator!=(const UEdge i) const {return id!=i.id;}
  1533       bool operator<(const UEdge i) const {return id<i.id;}
  1534     };
  1535 
  1536     ListBpUGraphBase()
  1537       : first_anode(-1), first_free_anode(-1),
  1538         first_bnode(-1), first_free_bnode(-1),
  1539         first_free_edge(-1) {}
  1540 
  1541     void firstANode(Node& node) const {
  1542       node.id = first_anode != -1 ? (first_anode << 1) : -1;
  1543     }
  1544     void nextANode(Node& node) const {
  1545       node.id = aNodes[node.id >> 1].next;
  1546     }
  1547 
  1548     void firstBNode(Node& node) const {
  1549       node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
  1550     }
  1551     void nextBNode(Node& node) const {
  1552       node.id = bNodes[node.id >> 1].next;
  1553     }
  1554 
  1555     void first(Node& node) const {
  1556       if (first_anode != -1) {
  1557         node.id = (first_anode << 1);
  1558       } else if (first_bnode != -1) {
  1559         node.id = (first_bnode << 1) + 1;
  1560       } else {
  1561         node.id = -1;
  1562       }
  1563     }
  1564     void next(Node& node) const {
  1565       if (aNode(node)) {
  1566         node.id = aNodes[node.id >> 1].next;
  1567         if (node.id == -1) {
  1568           if (first_bnode != -1) {
  1569             node.id = (first_bnode << 1) + 1;
  1570           }
  1571         }
  1572       } else {
  1573         node.id = bNodes[node.id >> 1].next;
  1574       }
  1575     }
  1576   
  1577     void first(UEdge& edge) const {
  1578       int aNodeId = first_anode;
  1579       while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
  1580         aNodeId = aNodes[aNodeId].next != -1 ? 
  1581           aNodes[aNodeId].next >> 1 : -1;
  1582       }
  1583       if (aNodeId != -1) {
  1584         edge.id = aNodes[aNodeId].first_edge;
  1585       } else {
  1586         edge.id = -1;
  1587       }
  1588     }
  1589     void next(UEdge& edge) const {
  1590       int aNodeId = edges[edge.id].aNode >> 1;
  1591       edge.id = edges[edge.id].next_out;
  1592       if (edge.id == -1) {
  1593         aNodeId = aNodes[aNodeId].next != -1 ? 
  1594           aNodes[aNodeId].next >> 1 : -1;
  1595         while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
  1596           aNodeId = aNodes[aNodeId].next != -1 ? 
  1597           aNodes[aNodeId].next >> 1 : -1;
  1598         }
  1599         if (aNodeId != -1) {
  1600           edge.id = aNodes[aNodeId].first_edge;
  1601         } else {
  1602           edge.id = -1;
  1603         }
  1604       }
  1605     }
  1606 
  1607     void firstFromANode(UEdge& edge, const Node& node) const {
  1608       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
  1609       edge.id = aNodes[node.id >> 1].first_edge;
  1610     }
  1611     void nextFromANode(UEdge& edge) const {
  1612       edge.id = edges[edge.id].next_out;
  1613     }
  1614 
  1615     void firstFromBNode(UEdge& edge, const Node& node) const {
  1616       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
  1617       edge.id = bNodes[node.id >> 1].first_edge;
  1618     }
  1619     void nextFromBNode(UEdge& edge) const {
  1620       edge.id = edges[edge.id].next_in;
  1621     }
  1622 
  1623     static int id(const Node& node) {
  1624       return node.id;
  1625     }
  1626     static Node nodeFromId(int id) {
  1627       return Node(id);
  1628     }
  1629     int maxNodeId() const {
  1630       return aNodes.size() > bNodes.size() ?
  1631 	aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
  1632     }
  1633   
  1634     static int id(const UEdge& edge) {
  1635       return edge.id;
  1636     }
  1637     static UEdge uEdgeFromId(int id) {
  1638       return UEdge(id);
  1639     }
  1640     int maxUEdgeId() const {
  1641       return edges.size();
  1642     }
  1643   
  1644     static int aNodeId(const Node& node) {
  1645       return node.id >> 1;
  1646     }
  1647     static Node nodeFromANodeId(int id) {
  1648       return Node(id << 1);
  1649     }
  1650     int maxANodeId() const {
  1651       return aNodes.size();
  1652     }
  1653 
  1654     static int bNodeId(const Node& node) {
  1655       return node.id >> 1;
  1656     }
  1657     static Node nodeFromBNodeId(int id) {
  1658       return Node((id << 1) + 1);
  1659     }
  1660     int maxBNodeId() const {
  1661       return bNodes.size();
  1662     }
  1663 
  1664     Node aNode(const UEdge& edge) const {
  1665       return Node(edges[edge.id].aNode);
  1666     }
  1667     Node bNode(const UEdge& edge) const {
  1668       return Node(edges[edge.id].bNode);
  1669     }
  1670 
  1671     static bool aNode(const Node& node) {
  1672       return (node.id & 1) == 0;
  1673     }
  1674 
  1675     static bool bNode(const Node& node) {
  1676       return (node.id & 1) == 1;
  1677     }
  1678 
  1679     Node addANode() {
  1680       int aNodeId;
  1681       if (first_free_anode == -1) {
  1682         aNodeId = aNodes.size();
  1683         aNodes.push_back(NodeT());
  1684       } else {
  1685         aNodeId = first_free_anode;
  1686         first_free_anode = aNodes[first_free_anode].next;
  1687       }
  1688       if (first_anode != -1) {
  1689         aNodes[aNodeId].next = first_anode << 1;
  1690         aNodes[first_anode].prev = aNodeId << 1;
  1691       } else {
  1692         aNodes[aNodeId].next = -1;
  1693       }
  1694       aNodes[aNodeId].prev = -1;
  1695       first_anode = aNodeId;
  1696       aNodes[aNodeId].first_edge = -1;
  1697       return Node(aNodeId << 1);
  1698     }
  1699 
  1700     Node addBNode() {
  1701       int bNodeId;
  1702       if (first_free_bnode == -1) {
  1703         bNodeId = bNodes.size();
  1704         bNodes.push_back(NodeT());
  1705       } else {
  1706         bNodeId = first_free_bnode;
  1707         first_free_bnode = bNodes[first_free_bnode].next;
  1708       }
  1709       if (first_bnode != -1) {
  1710         bNodes[bNodeId].next = (first_bnode << 1) + 1;
  1711         bNodes[first_bnode].prev = (bNodeId << 1) + 1;
  1712       } else {
  1713         bNodes[bNodeId].next = -1;
  1714       }
  1715       bNodes[bNodeId].prev = -1;
  1716       first_bnode = bNodeId;
  1717       bNodes[bNodeId].first_edge = -1;
  1718       return Node((bNodeId << 1) + 1);
  1719     }
  1720 
  1721     UEdge addEdge(const Node& source, const Node& target) {
  1722       LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
  1723       int edgeId;
  1724       if (first_free_edge != -1) {
  1725         edgeId = first_free_edge;
  1726         first_free_edge = edges[edgeId].next_out;
  1727       } else {
  1728         edgeId = edges.size();
  1729         edges.push_back(UEdgeT());
  1730       }
  1731       if ((source.id & 1) == 0) {
  1732 	edges[edgeId].aNode = source.id;
  1733 	edges[edgeId].bNode = target.id;
  1734       } else {
  1735 	edges[edgeId].aNode = target.id;
  1736 	edges[edgeId].bNode = source.id;
  1737       }
  1738       edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
  1739       edges[edgeId].prev_out = -1;
  1740       if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
  1741         edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
  1742       }
  1743       aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
  1744       edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
  1745       edges[edgeId].prev_in = -1;
  1746       if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
  1747         edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
  1748       }
  1749       bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
  1750       return UEdge(edgeId);
  1751     }
  1752 
  1753     void erase(const Node& node) {
  1754       if (aNode(node)) {
  1755         int aNodeId = node.id >> 1;
  1756         if (aNodes[aNodeId].prev != -1) {
  1757           aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
  1758         } else {
  1759           first_anode = 
  1760             aNodes[aNodeId].next != -1 ? aNodes[aNodeId].next >> 1 : -1;
  1761         }
  1762         if (aNodes[aNodeId].next != -1) {
  1763           aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
  1764         }
  1765         aNodes[aNodeId].next = first_free_anode;
  1766         first_free_anode = aNodeId;
  1767       } else {
  1768         int bNodeId = node.id >> 1;
  1769         if (bNodes[bNodeId].prev != -1) {
  1770           bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
  1771         } else {
  1772           first_bnode = 
  1773             bNodes[bNodeId].next != -1 ? bNodes[bNodeId].next >> 1 : -1;
  1774         }
  1775         if (bNodes[bNodeId].next != -1) {
  1776           bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
  1777         }
  1778         bNodes[bNodeId].next = first_free_bnode;
  1779         first_free_bnode = bNodeId;
  1780       }
  1781     }
  1782 
  1783     void erase(const UEdge& edge) {
  1784 
  1785       if (edges[edge.id].prev_out != -1) {
  1786         edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
  1787       } else {
  1788         aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
  1789       }
  1790       if (edges[edge.id].next_out != -1) {
  1791         edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
  1792       }
  1793 
  1794       if (edges[edge.id].prev_in != -1) {
  1795         edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
  1796       } else {
  1797         bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
  1798       }
  1799       if (edges[edge.id].next_in != -1) {
  1800         edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
  1801       }
  1802 
  1803       edges[edge.id].next_out = first_free_edge;
  1804       first_free_edge = edge.id;
  1805     }
  1806  
  1807     void clear() {
  1808       aNodes.clear();
  1809       bNodes.clear();
  1810       edges.clear();
  1811       first_anode = -1;
  1812       first_free_anode = -1;
  1813       first_bnode = -1;
  1814       first_free_bnode = -1;
  1815       first_free_edge = -1;
  1816     }
  1817 
  1818     void changeANode(const UEdge& edge, const Node& node) {
  1819       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
  1820       if (edges[edge.id].prev_out != -1) {
  1821         edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
  1822       } else {
  1823         aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
  1824       }
  1825       if (edges[edge.id].next_out != -1) {
  1826         edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;  
  1827       }
  1828       if (aNodes[node.id >> 1].first_edge != -1) {
  1829         edges[aNodes[node.id >> 1].first_edge].prev_out = edge.id;
  1830       }
  1831       edges[edge.id].prev_out = -1;
  1832       edges[edge.id].next_out = aNodes[node.id >> 1].first_edge;
  1833       aNodes[node.id >> 1].first_edge = edge.id;
  1834       edges[edge.id].aNode = node.id;
  1835     } 
  1836 
  1837     void changeBNode(const UEdge& edge, const Node& node) {
  1838       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
  1839       if (edges[edge.id].prev_in != -1) {
  1840         edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
  1841       } else {
  1842         bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
  1843       }
  1844       if (edges[edge.id].next_in != -1) {
  1845         edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;  
  1846       }
  1847       if (bNodes[node.id >> 1].first_edge != -1) {
  1848         edges[bNodes[node.id >> 1].first_edge].prev_in = edge.id;
  1849       }
  1850       edges[edge.id].prev_in = -1;
  1851       edges[edge.id].next_in = bNodes[node.id >> 1].first_edge;
  1852       bNodes[node.id >> 1].first_edge = edge.id;
  1853       edges[edge.id].bNode = node.id;
  1854     } 
  1855 
  1856   };
  1857 
  1858 
  1859   typedef BpUGraphExtender<BidirBpUGraphExtender<ListBpUGraphBase> > 
  1860   ExtendedListBpUGraphBase;
  1861 
  1862   /// \ingroup graphs
  1863   ///
  1864   /// \brief A smart bipartite undirected graph class.
  1865   ///
  1866   /// This is a bipartite undirected graph implementation.
  1867   /// It is conforms to the \ref concepts::BpUGraph "BpUGraph concept".
  1868   ///
  1869   ///An important extra feature of this graph implementation is that
  1870   ///its maps are real \ref concepts::ReferenceMap "reference map"s.
  1871   ///
  1872   /// \sa concepts::BpUGraph.
  1873   ///
  1874   class ListBpUGraph : public ExtendedListBpUGraphBase {
  1875     /// \brief ListBpUGraph is \e not copy constructible.
  1876     ///
  1877     ///ListBpUGraph is \e not copy constructible.
  1878     ListBpUGraph(const ListBpUGraph &) :ExtendedListBpUGraphBase()  {};
  1879     /// \brief Assignment of ListBpUGraph to another one is \e not
  1880     /// allowed.
  1881     ///
  1882     /// Assignment of ListBpUGraph to another one is \e not allowed.
  1883     void operator=(const ListBpUGraph &) {}
  1884   public:
  1885     /// \brief Constructor
  1886     ///    
  1887     /// Constructor.
  1888     ///
  1889     ListBpUGraph() {}
  1890 
  1891     typedef ExtendedListBpUGraphBase Parent;
  1892     /// \brief Add a new ANode to the graph.
  1893     ///
  1894     /// \return the new node.
  1895     ///
  1896     Node addANode() { return Parent::addANode(); }
  1897 
  1898     /// \brief Add a new BNode to the graph.
  1899     ///
  1900     /// \return the new node.
  1901     ///
  1902     Node addBNode() { return Parent::addBNode(); }
  1903 
  1904     /// \brief Add a new edge to the graph.
  1905     ///
  1906     /// Add a new edge to the graph with an ANode and a BNode.
  1907     /// \return the new undirected edge.
  1908     UEdge addEdge(const Node& s, const Node& t) { 
  1909       return Parent::addEdge(s, t); 
  1910     }
  1911 
  1912     /// \brief Changes the ANode of \c e to \c n
  1913     ///
  1914     /// Changes the ANode of \c e to \c n
  1915     ///
  1916     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
  1917     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
  1918     ///invalidated.
  1919     void changeANode(UEdge e, Node n) { 
  1920       Parent::changeANode(e,n); 
  1921     }
  1922 
  1923     /// \brief Changes the BNode of \c e to \c n
  1924     ///
  1925     /// Changes the BNode of \c e to \c n
  1926     ///
  1927     /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1928     /// referencing the changed edge remain
  1929     /// valid. However <tt>InEdgeIt</tt>s are invalidated.
  1930     void changeBNode(UEdge e, Node n) { 
  1931       Parent::changeBNode(e,n); 
  1932     }
  1933 
  1934     /// \brief Changes the source(ANode) of \c e to \c n
  1935     ///
  1936     /// Changes the source(ANode) of \c e to \c n
  1937     ///
  1938     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
  1939     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
  1940     ///invalidated.
  1941     void changeSource(UEdge e, Node n) { 
  1942       Parent::changeANode(e,n); 
  1943     }
  1944 
  1945     /// \brief Changes the target(BNode) of \c e to \c n
  1946     ///
  1947     /// Changes the target(BNode) of \c e to \c n
  1948     ///
  1949     /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1950     /// referencing the changed edge remain
  1951     /// valid. However <tt>InEdgeIt</tt>s are invalidated.
  1952     void changeTarget(UEdge e, Node n) { 
  1953       Parent::changeBNode(e,n); 
  1954     }
  1955 
  1956     /// \brief Changes the source of \c e to \c n
  1957     ///
  1958     /// Changes the source of \c e to \c n. It changes the proper
  1959     /// node of the represented undirected edge.
  1960     ///
  1961     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1962     ///referencing the changed edge remain
  1963     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1964     void changeSource(Edge e, Node n) { 
  1965       if (Parent::direction(e)) {
  1966         Parent::changeANode(e,n);
  1967       } else {
  1968         Parent::changeBNode(e,n);
  1969       } 
  1970     }
  1971     /// \brief Changes the target of \c e to \c n
  1972     ///
  1973     /// Changes the target of \c e to \c n. It changes the proper
  1974     /// node of the represented undirected edge.
  1975     ///
  1976     ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1977     ///referencing the changed edge remain
  1978     ///valid. However <tt>InEdgeIt</tt>s are invalidated.
  1979     void changeTarget(Edge e, Node n) { 
  1980       if (Parent::direction(e)) {
  1981         Parent::changeBNode(e,n);
  1982       } else {
  1983         Parent::changeANode(e,n);
  1984       } 
  1985     }
  1986     /// \brief Contract two nodes.
  1987     ///
  1988     /// This function contracts two nodes.
  1989     ///
  1990     /// Node \p b will be removed but instead of deleting its
  1991     /// neighboring edges, they will be joined to \p a.  The two nodes
  1992     /// should be from the same nodeset, of course.
  1993     ///
  1994     /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
  1995     /// valid.
  1996     void contract(const Node& a, const Node& b) {
  1997       LEMON_ASSERT(Parent::aNode(a) == Parent::aNode(b), NodeSetError());
  1998       if (Parent::aNode(a)) {
  1999         for (IncEdgeIt e(*this, b); e!=INVALID;) {
  2000           IncEdgeIt f = e; ++f;
  2001           changeSource(e, a);
  2002           e = f;
  2003         }
  2004       } else {
  2005         for (IncEdgeIt e(*this, b); e!=INVALID;) {
  2006           IncEdgeIt f = e; ++f;
  2007           changeTarget(e, a);
  2008           e = f;
  2009         }
  2010       }
  2011       erase(b);
  2012     }
  2013 
  2014     /// \brief Class to make a snapshot of the graph and restore
  2015     /// to it later.
  2016     ///
  2017     /// Class to make a snapshot of the graph and to restore it
  2018     /// later.
  2019     ///
  2020     /// The newly added nodes and undirected edges can be removed
  2021     /// using the restore() function.
  2022     ///
  2023     /// \warning Edge and node deletions cannot be restored. This
  2024     /// events invalidate the snapshot. 
  2025     class Snapshot {
  2026     protected:
  2027 
  2028       typedef Parent::NodeNotifier NodeNotifier;
  2029 
  2030       class NodeObserverProxy : public NodeNotifier::ObserverBase {
  2031       public:
  2032 
  2033         NodeObserverProxy(Snapshot& _snapshot)
  2034           : snapshot(_snapshot) {}
  2035 
  2036         using NodeNotifier::ObserverBase::attach;
  2037         using NodeNotifier::ObserverBase::detach;
  2038         using NodeNotifier::ObserverBase::attached;
  2039         
  2040       protected:
  2041         
  2042         virtual void add(const Node& node) {
  2043           snapshot.addNode(node);
  2044         }
  2045         virtual void add(const std::vector<Node>& nodes) {
  2046           for (int i = nodes.size() - 1; i >= 0; ++i) {
  2047             snapshot.addNode(nodes[i]);
  2048           }
  2049         }
  2050         virtual void erase(const Node& node) {
  2051           snapshot.eraseNode(node);
  2052         }
  2053         virtual void erase(const std::vector<Node>& nodes) {
  2054           for (int i = 0; i < (int)nodes.size(); ++i) {
  2055             snapshot.eraseNode(nodes[i]);
  2056           }
  2057         }
  2058         virtual void build() {
  2059           NodeNotifier* _notifier = notifier();
  2060           Node node;
  2061           std::vector<Node> nodes;
  2062           for (_notifier->first(node); node != INVALID; 
  2063                _notifier->next(node)) {
  2064             nodes.push_back(node);
  2065           }
  2066           for (int i = nodes.size() - 1; i >= 0; --i) {
  2067             snapshot.addNode(nodes[i]);
  2068           }
  2069         }
  2070         virtual void clear() {
  2071           NodeNotifier* _notifier = notifier();
  2072           Node node;
  2073           for (_notifier->first(node); node != INVALID; 
  2074                _notifier->next(node)) {
  2075             snapshot.eraseNode(node);
  2076           }
  2077         }
  2078 
  2079         Snapshot& snapshot;
  2080       };
  2081 
  2082       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
  2083       public:
  2084 
  2085         UEdgeObserverProxy(Snapshot& _snapshot)
  2086           : snapshot(_snapshot) {}
  2087 
  2088         using UEdgeNotifier::ObserverBase::attach;
  2089         using UEdgeNotifier::ObserverBase::detach;
  2090         using UEdgeNotifier::ObserverBase::attached;
  2091         
  2092       protected:
  2093 
  2094         virtual void add(const UEdge& edge) {
  2095           snapshot.addUEdge(edge);
  2096         }
  2097         virtual void add(const std::vector<UEdge>& edges) {
  2098           for (int i = edges.size() - 1; i >= 0; ++i) {
  2099             snapshot.addUEdge(edges[i]);
  2100           }
  2101         }
  2102         virtual void erase(const UEdge& edge) {
  2103           snapshot.eraseUEdge(edge);
  2104         }
  2105         virtual void erase(const std::vector<UEdge>& edges) {
  2106           for (int i = 0; i < (int)edges.size(); ++i) {
  2107             snapshot.eraseUEdge(edges[i]);
  2108           }
  2109         }
  2110         virtual void build() {
  2111           UEdgeNotifier* _notifier = notifier();
  2112           UEdge edge;
  2113           std::vector<UEdge> edges;
  2114           for (_notifier->first(edge); edge != INVALID; 
  2115                _notifier->next(edge)) {
  2116             edges.push_back(edge);
  2117           }
  2118           for (int i = edges.size() - 1; i >= 0; --i) {
  2119             snapshot.addUEdge(edges[i]);
  2120           }
  2121         }
  2122         virtual void clear() {
  2123           UEdgeNotifier* _notifier = notifier();
  2124           UEdge edge;
  2125           for (_notifier->first(edge); edge != INVALID; 
  2126                _notifier->next(edge)) {
  2127             snapshot.eraseUEdge(edge);
  2128           }
  2129         }
  2130 
  2131         Snapshot& snapshot;
  2132       };
  2133       
  2134       ListBpUGraph *graph;
  2135 
  2136       NodeObserverProxy node_observer_proxy;
  2137       UEdgeObserverProxy edge_observer_proxy;
  2138 
  2139       std::list<Node> added_nodes;
  2140       std::list<UEdge> added_edges;
  2141 
  2142 
  2143       void addNode(const Node& node) {
  2144         added_nodes.push_front(node);        
  2145       }
  2146       void eraseNode(const Node& node) {
  2147         std::list<Node>::iterator it = 
  2148           std::find(added_nodes.begin(), added_nodes.end(), node);
  2149         if (it == added_nodes.end()) {
  2150           clear();
  2151           edge_observer_proxy.detach();
  2152           throw NodeNotifier::ImmediateDetach();
  2153         } else {
  2154           added_nodes.erase(it);
  2155         }
  2156       }
  2157 
  2158       void addUEdge(const UEdge& edge) {
  2159         added_edges.push_front(edge);        
  2160       }
  2161       void eraseUEdge(const UEdge& edge) {
  2162         std::list<UEdge>::iterator it = 
  2163           std::find(added_edges.begin(), added_edges.end(), edge);
  2164         if (it == added_edges.end()) {
  2165           clear();
  2166           node_observer_proxy.detach();
  2167           throw UEdgeNotifier::ImmediateDetach();
  2168         } else {
  2169           added_edges.erase(it);
  2170         }        
  2171       }
  2172 
  2173       void attach(ListBpUGraph &_graph) {
  2174 	graph = &_graph;
  2175 	node_observer_proxy.attach(graph->notifier(Node()));
  2176         edge_observer_proxy.attach(graph->notifier(UEdge()));
  2177       }
  2178             
  2179       void detach() {
  2180 	node_observer_proxy.detach();
  2181 	edge_observer_proxy.detach();
  2182       }
  2183 
  2184       bool attached() const {
  2185         return node_observer_proxy.attached();
  2186       }
  2187 
  2188       void clear() {
  2189         added_nodes.clear();
  2190         added_edges.clear();        
  2191       }
  2192 
  2193     public:
  2194 
  2195       /// \brief Default constructor.
  2196       ///
  2197       /// Default constructor.
  2198       /// To actually make a snapshot you must call save().
  2199       Snapshot() 
  2200         : graph(0), node_observer_proxy(*this), 
  2201           edge_observer_proxy(*this) {}
  2202       
  2203       /// \brief Constructor that immediately makes a snapshot.
  2204       ///      
  2205       /// This constructor immediately makes a snapshot of the graph.
  2206       /// \param _graph The graph we make a snapshot of.
  2207       Snapshot(ListBpUGraph &_graph) 
  2208         : node_observer_proxy(*this), 
  2209           edge_observer_proxy(*this) {
  2210 	attach(_graph);
  2211       }
  2212       
  2213       /// \brief Make a snapshot.
  2214       ///
  2215       /// Make a snapshot of the graph.
  2216       ///
  2217       /// This function can be called more than once. In case of a repeated
  2218       /// call, the previous snapshot gets lost.
  2219       /// \param _graph The graph we make the snapshot of.
  2220       void save(ListBpUGraph &_graph) {
  2221         if (attached()) {
  2222           detach();
  2223           clear();
  2224         }
  2225         attach(_graph);
  2226       }
  2227       
  2228       /// \brief Undo the changes until the last snapshot.
  2229       // 
  2230       /// Undo the changes until the last snapshot created by save().
  2231       void restore() {
  2232 	detach();
  2233 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
  2234             it != added_edges.end(); ++it) {
  2235 	  graph->erase(*it);
  2236 	}
  2237 	for(std::list<Node>::iterator it = added_nodes.begin(); 
  2238             it != added_nodes.end(); ++it) {
  2239 	  graph->erase(*it);
  2240 	}
  2241         clear();
  2242       }
  2243 
  2244       /// \brief Gives back true when the snapshot is valid.
  2245       ///
  2246       /// Gives back true when the snapshot is valid.
  2247       bool valid() const {
  2248         return attached();
  2249       }
  2250     };
  2251   };
  2252 
  2253   
  2254   /// @}  
  2255 } //namespace lemon
  2256   
  2257 
  2258 #endif