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