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