lemon/list_graph.h
author alpar
Thu, 07 Sep 2006 13:34:14 +0000
changeset 2208 37b5c870a953
parent 2160 abd867cf8a9c
child 2231 06faf3f06d67
permissions -rw-r--r--
Revert an unintentional commit in r2933
     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 fromANodeId(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 fromBNodeId(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< ListBpUGraphBase > ExtendedListBpUGraphBase;
  1486 
  1487   /// \ingroup graphs
  1488   ///
  1489   /// \brief A smart bipartite undirected graph class.
  1490   ///
  1491   /// This is a bipartite undirected graph implementation.
  1492   /// It is conforms to the \ref concept::BpUGraph "BpUGraph concept".
  1493   /// \sa concept::BpUGraph.
  1494   ///
  1495   class ListBpUGraph : public ExtendedListBpUGraphBase {
  1496     /// \brief ListBpUGraph is \e not copy constructible.
  1497     ///
  1498     ///ListBpUGraph is \e not copy constructible.
  1499     ListBpUGraph(const ListBpUGraph &) :ExtendedListBpUGraphBase()  {};
  1500     /// \brief Assignment of ListBpUGraph to another one is \e not
  1501     /// allowed.
  1502     ///
  1503     /// Assignment of ListBpUGraph to another one is \e not allowed.
  1504     void operator=(const ListBpUGraph &) {}
  1505   public:
  1506     /// \brief Constructor
  1507     ///    
  1508     /// Constructor.
  1509     ///
  1510     ListBpUGraph() {}
  1511 
  1512     typedef ExtendedListBpUGraphBase Parent;
  1513     /// \brief Add a new ANode to the graph.
  1514     ///
  1515     /// \return the new node.
  1516     ///
  1517     Node addANode() { return Parent::addANode(); }
  1518 
  1519     /// \brief Add a new BNode to the graph.
  1520     ///
  1521     /// \return the new node.
  1522     ///
  1523     Node addBNode() { return Parent::addBNode(); }
  1524 
  1525     /// \brief Add a new edge to the graph.
  1526     ///
  1527     /// Add a new edge to the graph with an ANode and a BNode.
  1528     /// \return the new undirected edge.
  1529     UEdge addEdge(const Node& s, const Node& t) { 
  1530       return Parent::addEdge(s, t); 
  1531     }
  1532 
  1533     /// \brief Changes the ANode of \c e to \c n
  1534     ///
  1535     /// Changes the ANode of \c e to \c n
  1536     ///
  1537     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
  1538     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
  1539     ///invalidated.
  1540     void changeANode(UEdge e, Node n) { 
  1541       Parent::changeANode(e,n); 
  1542     }
  1543 
  1544     /// \brief Changes the BNode of \c e to \c n
  1545     ///
  1546     /// Changes the BNode of \c e to \c n
  1547     ///
  1548     /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1549     /// referencing the changed edge remain
  1550     /// valid. However <tt>InEdgeIt</tt>s are invalidated.
  1551     void changeBNode(UEdge e, Node n) { 
  1552       Parent::changeBNode(e,n); 
  1553     }
  1554 
  1555     /// \brief Changes the source(ANode) of \c e to \c n
  1556     ///
  1557     /// Changes the source(ANode) of \c e to \c n
  1558     ///
  1559     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
  1560     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
  1561     ///invalidated.
  1562     void changeSource(UEdge e, Node n) { 
  1563       Parent::changeANode(e,n); 
  1564     }
  1565 
  1566     /// \brief Changes the target(BNode) of \c e to \c n
  1567     ///
  1568     /// Changes the target(BNode) of \c e to \c n
  1569     ///
  1570     /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1571     /// referencing the changed edge remain
  1572     /// valid. However <tt>InEdgeIt</tt>s are invalidated.
  1573     void changeTarget(UEdge e, Node n) { 
  1574       Parent::changeBNode(e,n); 
  1575     }
  1576 
  1577     /// \brief Changes the source of \c e to \c n
  1578     ///
  1579     /// Changes the source of \c e to \c n. It changes the proper
  1580     /// node of the represented undirected edge.
  1581     ///
  1582     ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
  1583     ///referencing the changed edge remain
  1584     ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
  1585     void changeSource(Edge e, Node n) { 
  1586       if (Parent::direction(e)) {
  1587         Parent::changeANode(e,n);
  1588       } else {
  1589         Parent::changeBNode(e,n);
  1590       } 
  1591     }
  1592     /// \brief Changes the target of \c e to \c n
  1593     ///
  1594     /// Changes the target of \c e to \c n. It changes the proper
  1595     /// node of the represented undirected edge.
  1596     ///
  1597     ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
  1598     ///referencing the changed edge remain
  1599     ///valid. However <tt>InEdgeIt</tt>s are invalidated.
  1600     void changeTarget(Edge e, Node n) { 
  1601       if (Parent::direction(e)) {
  1602         Parent::changeBNode(e,n);
  1603       } else {
  1604         Parent::changeANode(e,n);
  1605       } 
  1606     }
  1607     /// \brief Contract two nodes.
  1608     ///
  1609     /// This function contracts two nodes.
  1610     ///
  1611     /// Node \p b will be removed but instead of deleting its
  1612     /// neighboring edges, they will be joined to \p a.  The two nodes
  1613     /// should be from the same nodeset, of course.
  1614     ///
  1615     /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
  1616     /// valid.
  1617     void contract(const Node& a, const Node& b) {
  1618       LEMON_ASSERT(Parent::aNode(a) == Parent::aNode(b), NodeSetError());
  1619       if (Parent::aNode(a)) {
  1620         for (IncEdgeIt e(*this, b); e!=INVALID;) {
  1621           IncEdgeIt f = e; ++f;
  1622           changeSource(e, a);
  1623           e = f;
  1624         }
  1625       } else {
  1626         for (IncEdgeIt e(*this, b); e!=INVALID;) {
  1627           IncEdgeIt f = e; ++f;
  1628           changeTarget(e, a);
  1629           e = f;
  1630         }
  1631       }
  1632       erase(b);
  1633     }
  1634 
  1635     /// \brief Class to make a snapshot of the graph and restore
  1636     /// to it later.
  1637     ///
  1638     /// Class to make a snapshot of the graph and to restore it
  1639     /// later.
  1640     ///
  1641     /// The newly added nodes and undirected edges can be removed
  1642     /// using the restore() function.
  1643     ///
  1644     /// \warning Edge and node deletions cannot be restored. This
  1645     /// events invalidate the snapshot. 
  1646     class Snapshot {
  1647     protected:
  1648 
  1649       typedef Parent::NodeNotifier NodeNotifier;
  1650 
  1651       class NodeObserverProxy : public NodeNotifier::ObserverBase {
  1652       public:
  1653 
  1654         NodeObserverProxy(Snapshot& _snapshot)
  1655           : snapshot(_snapshot) {}
  1656 
  1657         using NodeNotifier::ObserverBase::attach;
  1658         using NodeNotifier::ObserverBase::detach;
  1659         using NodeNotifier::ObserverBase::attached;
  1660         
  1661       protected:
  1662         
  1663         virtual void add(const Node& node) {
  1664           snapshot.addNode(node);
  1665         }
  1666         virtual void add(const std::vector<Node>& nodes) {
  1667           for (int i = nodes.size() - 1; i >= 0; ++i) {
  1668             snapshot.addNode(nodes[i]);
  1669           }
  1670         }
  1671         virtual void erase(const Node& node) {
  1672           snapshot.eraseNode(node);
  1673         }
  1674         virtual void erase(const std::vector<Node>& nodes) {
  1675           for (int i = 0; i < (int)nodes.size(); ++i) {
  1676             snapshot.eraseNode(nodes[i]);
  1677           }
  1678         }
  1679         virtual void build() {
  1680           NodeNotifier* notifier = getNotifier();
  1681           Node node;
  1682           std::vector<Node> nodes;
  1683           for (notifier->first(node); node != INVALID; notifier->next(node)) {
  1684             nodes.push_back(node);
  1685           }
  1686           for (int i = nodes.size() - 1; i >= 0; --i) {
  1687             snapshot.addNode(nodes[i]);
  1688           }
  1689         }
  1690         virtual void clear() {
  1691           NodeNotifier* notifier = getNotifier();
  1692           Node node;
  1693           for (notifier->first(node); node != INVALID; notifier->next(node)) {
  1694             snapshot.eraseNode(node);
  1695           }
  1696         }
  1697 
  1698         Snapshot& snapshot;
  1699       };
  1700 
  1701       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
  1702       public:
  1703 
  1704         UEdgeObserverProxy(Snapshot& _snapshot)
  1705           : snapshot(_snapshot) {}
  1706 
  1707         using UEdgeNotifier::ObserverBase::attach;
  1708         using UEdgeNotifier::ObserverBase::detach;
  1709         using UEdgeNotifier::ObserverBase::attached;
  1710         
  1711       protected:
  1712 
  1713         virtual void add(const UEdge& edge) {
  1714           snapshot.addUEdge(edge);
  1715         }
  1716         virtual void add(const std::vector<UEdge>& edges) {
  1717           for (int i = edges.size() - 1; i >= 0; ++i) {
  1718             snapshot.addUEdge(edges[i]);
  1719           }
  1720         }
  1721         virtual void erase(const UEdge& edge) {
  1722           snapshot.eraseUEdge(edge);
  1723         }
  1724         virtual void erase(const std::vector<UEdge>& edges) {
  1725           for (int i = 0; i < (int)edges.size(); ++i) {
  1726             snapshot.eraseUEdge(edges[i]);
  1727           }
  1728         }
  1729         virtual void build() {
  1730           UEdgeNotifier* notifier = getNotifier();
  1731           UEdge edge;
  1732           std::vector<UEdge> edges;
  1733           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
  1734             edges.push_back(edge);
  1735           }
  1736           for (int i = edges.size() - 1; i >= 0; --i) {
  1737             snapshot.addUEdge(edges[i]);
  1738           }
  1739         }
  1740         virtual void clear() {
  1741           UEdgeNotifier* notifier = getNotifier();
  1742           UEdge edge;
  1743           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
  1744             snapshot.eraseUEdge(edge);
  1745           }
  1746         }
  1747 
  1748         Snapshot& snapshot;
  1749       };
  1750       
  1751       ListBpUGraph *graph;
  1752 
  1753       NodeObserverProxy node_observer_proxy;
  1754       UEdgeObserverProxy edge_observer_proxy;
  1755 
  1756       std::list<Node> added_nodes;
  1757       std::list<UEdge> added_edges;
  1758 
  1759 
  1760       void addNode(const Node& node) {
  1761         added_nodes.push_front(node);        
  1762       }
  1763       void eraseNode(const Node& node) {
  1764         std::list<Node>::iterator it = 
  1765           std::find(added_nodes.begin(), added_nodes.end(), node);
  1766         if (it == added_nodes.end()) {
  1767           clear();
  1768           edge_observer_proxy.detach();
  1769           throw NodeNotifier::ImmediateDetach();
  1770         } else {
  1771           added_nodes.erase(it);
  1772         }
  1773       }
  1774 
  1775       void addUEdge(const UEdge& edge) {
  1776         added_edges.push_front(edge);        
  1777       }
  1778       void eraseUEdge(const UEdge& edge) {
  1779         std::list<UEdge>::iterator it = 
  1780           std::find(added_edges.begin(), added_edges.end(), edge);
  1781         if (it == added_edges.end()) {
  1782           clear();
  1783           node_observer_proxy.detach();
  1784           throw UEdgeNotifier::ImmediateDetach();
  1785         } else {
  1786           added_edges.erase(it);
  1787         }        
  1788       }
  1789 
  1790       void attach(ListBpUGraph &_graph) {
  1791 	graph = &_graph;
  1792 	node_observer_proxy.attach(graph->getNotifier(Node()));
  1793         edge_observer_proxy.attach(graph->getNotifier(UEdge()));
  1794       }
  1795             
  1796       void detach() {
  1797 	node_observer_proxy.detach();
  1798 	edge_observer_proxy.detach();
  1799       }
  1800 
  1801       bool attached() const {
  1802         return node_observer_proxy.attached();
  1803       }
  1804 
  1805       void clear() {
  1806         added_nodes.clear();
  1807         added_edges.clear();        
  1808       }
  1809 
  1810     public:
  1811 
  1812       /// \brief Default constructor.
  1813       ///
  1814       /// Default constructor.
  1815       /// To actually make a snapshot you must call save().
  1816       Snapshot() 
  1817         : graph(0), node_observer_proxy(*this), 
  1818           edge_observer_proxy(*this) {}
  1819       
  1820       /// \brief Constructor that immediately makes a snapshot.
  1821       ///      
  1822       /// This constructor immediately makes a snapshot of the graph.
  1823       /// \param _graph The graph we make a snapshot of.
  1824       Snapshot(ListBpUGraph &_graph) 
  1825         : node_observer_proxy(*this), 
  1826           edge_observer_proxy(*this) {
  1827 	attach(_graph);
  1828       }
  1829       
  1830       /// \brief Make a snapshot.
  1831       ///
  1832       /// Make a snapshot of the graph.
  1833       ///
  1834       /// This function can be called more than once. In case of a repeated
  1835       /// call, the previous snapshot gets lost.
  1836       /// \param _graph The graph we make the snapshot of.
  1837       void save(ListBpUGraph &_graph) {
  1838         if (attached()) {
  1839           detach();
  1840           clear();
  1841         }
  1842         attach(_graph);
  1843       }
  1844       
  1845       /// \brief Undo the changes until the last snapshot.
  1846       // 
  1847       /// Undo the changes until the last snapshot created by save().
  1848       void restore() {
  1849 	detach();
  1850 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
  1851             it != added_edges.end(); ++it) {
  1852 	  graph->erase(*it);
  1853 	}
  1854 	for(std::list<Node>::iterator it = added_nodes.begin(); 
  1855             it != added_nodes.end(); ++it) {
  1856 	  graph->erase(*it);
  1857 	}
  1858         clear();
  1859       }
  1860 
  1861       /// \brief Gives back true when the snapshot is valid.
  1862       ///
  1863       /// Gives back true when the snapshot is valid.
  1864       bool valid() const {
  1865         return attached();
  1866       }
  1867     };
  1868   };
  1869 
  1870   
  1871   /// @}  
  1872 } //namespace lemon
  1873   
  1874 
  1875 #endif