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