lemon/list_graph.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2189 de2b77e3868c
child 2256 b22dfb6c5ff3
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

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