lemon/list_graph.h
author deba
Tue, 11 Jul 2006 15:42:15 +0000
changeset 2126 2c8adbee9fa6
parent 2117 96efb4fa0736
child 2128 509846825ddf
permissions -rw-r--r--
Renameing file: graph_component.h => graph_components.h
     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   public:
   329 
   330     typedef ExtendedListGraphBase Parent;
   331 
   332     ///Add a new node to the graph.
   333     
   334     /// \return the new node.
   335     ///
   336     Node addNode() { return Parent::addNode(); }
   337 
   338     ///Add a new edge to the graph.
   339     
   340     ///Add a new edge to the graph with source node \c s
   341     ///and target node \c t.
   342     ///\return the new edge.
   343     Edge addEdge(const Node& s, const Node& t) { 
   344       return Parent::addEdge(s, t); 
   345     }
   346 
   347     /// Changes the target of \c e to \c n
   348 
   349     /// Changes the target of \c e to \c n
   350     ///
   351     ///\note The <tt>Edge</tt>s and <tt>OutEdgeIt</tt>s referencing
   352     ///the changed edge remain valid. However <tt>InEdgeIt</tt>s are
   353     ///invalidated.
   354     ///\warning This functionality cannot be used together with the Snapshot
   355     ///feature.
   356     void changeTarget(Edge e, Node n) { 
   357       Parent::changeTarget(e,n); 
   358     }
   359     /// Changes the source of \c e to \c n
   360 
   361     /// Changes the source of \c e to \c n
   362     ///
   363     ///\note The <tt>Edge</tt>s and <tt>InEdgeIt</tt>s referencing
   364     ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
   365     ///invalidated.
   366     ///\warning This functionality cannot be used together with the Snapshot
   367     ///feature.
   368     void changeSource(Edge e, Node n) { 
   369       Parent::changeSource(e,n);
   370     }
   371 
   372     /// Invert the direction of an edge.
   373 
   374     ///\note The <tt>Edge</tt>s referencing the changed edge remain
   375     ///valid. However <tt>OutEdgeIt</tt>s and <tt>InEdgeIt</tt>s are
   376     ///invalidated.
   377     ///\warning This functionality cannot be used together with the Snapshot
   378     ///feature.
   379     void reverseEdge(Edge e) {
   380       Node t=target(e);
   381       changeTarget(e,source(e));
   382       changeSource(e,t);
   383     }
   384 
   385     /// \brief Using this it is possible to avoid the superfluous memory
   386     /// allocation.
   387 
   388     ///Using this it is possible to avoid the superfluous memory
   389     ///allocation: if you know that the graph you want to build will
   390     ///contain at least 10 million nodes then it is worth reserving
   391     ///space for this amount before starting to build the graph.
   392     void reserveNode(int n) { nodes.reserve(n); };
   393 
   394     /// \brief Using this it is possible to avoid the superfluous memory
   395     /// allocation.
   396 
   397     ///Using this it is possible to avoid the superfluous memory
   398     ///allocation: see the \ref reserveNode function.
   399     void reserveEdge(int n) { edges.reserve(n); };
   400 
   401 
   402     ///Contract two nodes.
   403 
   404     ///This function contracts two nodes.
   405     ///
   406     ///Node \p b will be removed but instead of deleting
   407     ///incident edges, they will be joined to \p a.
   408     ///The last parameter \p r controls whether to remove loops. \c true
   409     ///means that loops will be removed.
   410     ///
   411     ///\note The <tt>Edge</tt>s
   412     ///referencing a moved edge remain
   413     ///valid. However <tt>InEdge</tt>s and <tt>OutEdge</tt>s
   414     ///may be invalidated.
   415     ///\warning This functionality cannot be used together with the Snapshot
   416     ///feature.
   417     void contract(Node a, Node b, bool r = true) 
   418     {
   419       for(OutEdgeIt e(*this,b);e!=INVALID;) {
   420 	OutEdgeIt f=e;
   421 	++f;
   422 	if(r && target(e)==a) erase(e);
   423 	else changeSource(e,a);
   424 	e=f;
   425       }
   426       for(InEdgeIt e(*this,b);e!=INVALID;) {
   427 	InEdgeIt f=e;
   428 	++f;
   429 	if(r && source(e)==a) erase(e);
   430 	else changeTarget(e,a);
   431 	e=f;
   432       }
   433       erase(b);
   434     }
   435 
   436     ///Split a node.
   437 
   438     ///This function splits a node. First a new node is added to the graph,
   439     ///then the source of each outgoing edge of \c n is moved to this new node.
   440     ///If \c connect is \c true (this is the default value), then a new edge
   441     ///from \c n to the newly created node is also added.
   442     ///\return The newly created node.
   443     ///
   444     ///\note The <tt>Edge</tt>s
   445     ///referencing a moved edge remain
   446     ///valid. However <tt>InEdge</tt>s and <tt>OutEdge</tt>s
   447     ///may be invalidated.
   448     ///\warning This functionality cannot be used together with the Snapshot
   449     ///feature.
   450     ///\todo It could be implemented in a bit faster way.
   451     Node split(Node n, bool connect = true) {
   452       Node b = addNode();
   453       for(OutEdgeIt e(*this,n);e!=INVALID;) {
   454  	OutEdgeIt f=e;
   455 	++f;
   456 	changeSource(e,b);
   457 	e=f;
   458       }
   459       if (connect) addEdge(n,b);
   460       return b;
   461     }
   462       
   463     ///Split an edge.
   464 
   465     ///This function splits an edge. First a new node \c b is added to
   466     ///the graph, then the original edge is re-targeted to \c
   467     ///b. Finally an edge from \c b to the original target is added.
   468     ///\return The newly created node.  
   469     ///\warning This functionality
   470     ///cannot be used together with the Snapshot feature.
   471     Node split(Edge e) {
   472       Node b = addNode();
   473       addEdge(b,target(e));
   474       changeTarget(e,b);
   475       return b;
   476     }
   477       
   478     /// \brief Class to make a snapshot of the graph and restore
   479     /// to it later.
   480     ///
   481     /// Class to make a snapshot of the graph and to restore it
   482     /// later.
   483     ///
   484     /// The newly added nodes and edges can be removed using the
   485     /// restore() function.
   486     ///
   487     /// \warning Edge and node deletions cannot be restored.
   488     class Snapshot {
   489     public:
   490       
   491       class UnsupportedOperation : public LogicError {
   492       public:
   493 	virtual const char* exceptionName() const {
   494 	  return "lemon::ListGraph::Snapshot::UnsupportedOperation";
   495 	}
   496       };
   497             
   498 
   499     protected:
   500 
   501       typedef Parent::NodeNotifier NodeNotifier;
   502 
   503       class NodeObserverProxy : public NodeNotifier::ObserverBase {
   504       public:
   505 
   506         NodeObserverProxy(Snapshot& _snapshot)
   507           : snapshot(_snapshot) {}
   508 
   509         using NodeNotifier::ObserverBase::attach;
   510         using NodeNotifier::ObserverBase::detach;
   511         using NodeNotifier::ObserverBase::attached;
   512         
   513       protected:
   514         
   515         virtual void add(const Node& node) {
   516           snapshot.addNode(node);
   517         }
   518         virtual void add(const std::vector<Node>& nodes) {
   519           for (int i = nodes.size() - 1; i >= 0; ++i) {
   520             snapshot.addNode(nodes[i]);
   521           }
   522         }
   523         virtual void erase(const Node& node) {
   524           snapshot.eraseNode(node);
   525         }
   526         virtual void erase(const std::vector<Node>& nodes) {
   527           for (int i = 0; i < (int)nodes.size(); ++i) {
   528             if (!snapshot.eraseNode(nodes[i])) break;
   529           }
   530         }
   531         virtual void build() {
   532           NodeNotifier* notifier = getNotifier();
   533           Node node;
   534           std::vector<Node> nodes;
   535           for (notifier->first(node); node != INVALID; notifier->next(node)) {
   536             nodes.push_back(node);
   537           }
   538           for (int i = nodes.size() - 1; i >= 0; --i) {
   539             snapshot.addNode(nodes[i]);
   540           }
   541         }
   542         virtual void clear() {
   543           NodeNotifier* notifier = getNotifier();
   544           Node node;
   545           for (notifier->first(node); node != INVALID; notifier->next(node)) {
   546             if (!snapshot.eraseNode(node)) break;
   547           }
   548         }
   549 
   550         Snapshot& snapshot;
   551       };
   552 
   553       class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
   554       public:
   555 
   556         EdgeObserverProxy(Snapshot& _snapshot)
   557           : snapshot(_snapshot) {}
   558 
   559         using EdgeNotifier::ObserverBase::attach;
   560         using EdgeNotifier::ObserverBase::detach;
   561         using EdgeNotifier::ObserverBase::attached;
   562         
   563       protected:
   564 
   565         virtual void add(const Edge& edge) {
   566           snapshot.addEdge(edge);
   567         }
   568         virtual void add(const std::vector<Edge>& edges) {
   569           for (int i = edges.size() - 1; i >= 0; ++i) {
   570             snapshot.addEdge(edges[i]);
   571           }
   572         }
   573         virtual void erase(const Edge& edge) {
   574           snapshot.eraseEdge(edge);
   575         }
   576         virtual void erase(const std::vector<Edge>& edges) {
   577           for (int i = 0; i < (int)edges.size(); ++i) {
   578             if (!snapshot.eraseEdge(edges[i])) break;
   579           }
   580         }
   581         virtual void build() {
   582           EdgeNotifier* notifier = getNotifier();
   583           Edge edge;
   584           std::vector<Edge> edges;
   585           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
   586             edges.push_back(edge);
   587           }
   588           for (int i = edges.size() - 1; i >= 0; --i) {
   589             snapshot.addEdge(edges[i]);
   590           }
   591         }
   592         virtual void clear() {
   593           EdgeNotifier* notifier = getNotifier();
   594           Edge edge;
   595           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
   596             if (!snapshot.eraseEdge(edge)) break;
   597           }
   598         }
   599 
   600         Snapshot& snapshot;
   601       };
   602       
   603       ListGraph *graph;
   604 
   605       NodeObserverProxy node_observer_proxy;
   606       EdgeObserverProxy edge_observer_proxy;
   607 
   608       std::list<Node> added_nodes;
   609       std::list<Edge> added_edges;
   610 
   611 
   612       void addNode(const Node& node) {
   613         added_nodes.push_front(node);        
   614       }
   615       bool eraseNode(const Node& node) {
   616         std::list<Node>::iterator it = 
   617           std::find(added_nodes.begin(), added_nodes.end(), node);
   618         if (it == added_nodes.end()) {
   619           clear();
   620           return false;
   621         } else {
   622           added_nodes.erase(it);
   623           return true;
   624         }
   625       }
   626 
   627       void addEdge(const Edge& edge) {
   628         added_edges.push_front(edge);        
   629       }
   630       bool eraseEdge(const Edge& edge) {
   631         std::list<Edge>::iterator it = 
   632           std::find(added_edges.begin(), added_edges.end(), edge);
   633         if (it == added_edges.end()) {
   634           clear();
   635           return false;
   636         } else {
   637           added_edges.erase(it);
   638           return true;
   639         }        
   640       }
   641 
   642       void attach(ListGraph &_graph) {
   643 	graph = &_graph;
   644 	node_observer_proxy.attach(graph->getNotifier(Node()));
   645         edge_observer_proxy.attach(graph->getNotifier(Edge()));
   646       }
   647             
   648       void detach() {
   649 	node_observer_proxy.detach();
   650 	edge_observer_proxy.detach();
   651       }
   652 
   653       void clear() {
   654         detach();
   655         added_nodes.clear();
   656         added_edges.clear();        
   657       }
   658 
   659     public:
   660 
   661       /// \brief Default constructur.
   662       ///
   663       /// Default constructor.
   664       /// To actually make a snapshot you must call save().
   665       Snapshot() 
   666         : graph(0), node_observer_proxy(*this), 
   667           edge_observer_proxy(*this) {}
   668       
   669       /// \brief Constructor that immediately makes a snapshot.
   670       ///      
   671       /// This constructor immediately makes a snapshot of the graph.
   672       /// \param _graph The graph we make a snapshot of.
   673       Snapshot(ListGraph &_graph) 
   674         : node_observer_proxy(*this), 
   675           edge_observer_proxy(*this) {
   676 	attach(_graph);
   677       }
   678       
   679       /// \brief Make a snapshot.
   680       ///
   681       /// Make a snapshot of the graph.
   682       ///
   683       /// This function can be called more than once. In case of a repeated
   684       /// call, the previous snapshot gets lost.
   685       /// \param _graph The graph we make the snapshot of.
   686       void save(ListGraph &_graph) {
   687         clear();
   688         attach(_graph);
   689       }
   690       
   691       /// \brief Undo the changes until the last snapshot.
   692       // 
   693       /// Undo the changes until the last snapshot created by save().
   694       void restore() {
   695 	detach();
   696 	while(!added_edges.empty()) {
   697 	  graph->erase(added_edges.front());
   698 	  added_edges.pop_front();
   699 	}
   700  	while(!added_nodes.empty()) {
   701 	  graph->erase(added_nodes.front());
   702 	  added_nodes.pop_front();
   703 	}
   704       }
   705 
   706       /// \brief Gives back true when the snapshot is valid.
   707       ///
   708       /// Gives back true when the snapshot is valid.
   709       bool valid() const {
   710         return node_observer_proxy.attached();
   711       }
   712     };
   713     
   714   };
   715 
   716   ///@}
   717 
   718   /**************** Undirected List Graph ****************/
   719 
   720   typedef UGraphExtender<UndirGraphExtender<ListGraphBase> > 
   721   ExtendedListUGraphBase;
   722 
   723   /// \addtogroup graphs
   724   /// @{
   725 
   726   ///An undirected list graph class.
   727 
   728   ///This is a simple and fast undirected graph implementation.
   729   ///
   730   ///It conforms to the
   731   ///\ref concept::UGraph "UGraph concept".
   732   ///
   733   ///\sa concept::UGraph.
   734   ///
   735   ///\todo Snapshot, reverseEdge(), changeTarget(), changeSource(), contract()
   736   ///haven't been implemented yet.
   737   ///
   738   class ListUGraph : public ExtendedListUGraphBase {
   739   public:
   740     typedef ExtendedListUGraphBase Parent;
   741     /// \brief Add a new node to the graph.
   742     ///
   743     /// \return the new node.
   744     ///
   745     Node addNode() { return Parent::addNode(); }
   746 
   747     /// \brief Add a new edge to the graph.
   748     ///
   749     /// Add a new edge to the graph with source node \c s
   750     /// and target node \c t.
   751     /// \return the new undirected edge.
   752     UEdge addEdge(const Node& s, const Node& t) { 
   753       return Parent::addEdge(s, t); 
   754     }
   755     /// \brief Changes the target of \c e to \c n
   756     ///
   757     /// Changes the target of \c e to \c n
   758     ///
   759     /// \note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
   760     /// referencing the changed edge remain
   761     /// valid. However <tt>InEdge</tt>'s are invalidated.
   762     void changeTarget(UEdge e, Node n) { 
   763       Parent::changeTarget(e,n); 
   764     }
   765     /// Changes the source of \c e to \c n
   766     ///
   767     /// Changes the source of \c e to \c n
   768     ///
   769     ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
   770     ///referencing the changed edge remain
   771     ///valid. However <tt>OutEdge</tt>'s are invalidated.
   772     void changeSource(UEdge e, Node n) { 
   773       Parent::changeSource(e,n); 
   774     }
   775     /// \brief Contract two nodes.
   776     ///
   777     /// This function contracts two nodes.
   778     ///
   779     /// Node \p b will be removed but instead of deleting
   780     /// its neighboring edges, they will be joined to \p a.
   781     /// The last parameter \p r controls whether to remove loops. \c true
   782     /// means that loops will be removed.
   783     ///
   784     /// \note The <tt>Edge</tt>s
   785     /// referencing a moved edge remain
   786     /// valid.
   787     void contract(Node a, Node b, bool r = true) {
   788       for(IncEdgeIt e(*this, b); e!=INVALID;) {
   789 	IncEdgeIt f = e; ++f;
   790 	if (r && runningNode(e) == a) {
   791 	  erase(e);
   792 	} else if (source(e) == b) {
   793 	  changeSource(e, a);
   794 	} else {
   795 	  changeTarget(e, a);
   796 	}
   797 	e = f;
   798       }
   799       erase(b);
   800     }
   801   };
   802 
   803 
   804   class ListBpUGraphBase {
   805   public:
   806 
   807     class NodeSetError : public LogicError {
   808       virtual const char* exceptionName() const { 
   809 	return "lemon::ListBpUGraph::NodeSetError";
   810       }
   811     };
   812 
   813   protected:
   814 
   815     struct NodeT {
   816       int first_edge, prev, next;
   817     };
   818 
   819     struct UEdgeT {
   820       int aNode, prev_out, next_out;
   821       int bNode, prev_in, next_in;
   822     };
   823 
   824     std::vector<NodeT> aNodes;
   825     std::vector<NodeT> bNodes;
   826 
   827     std::vector<UEdgeT> edges;
   828 
   829     int first_anode;
   830     int first_free_anode;
   831 
   832     int first_bnode;
   833     int first_free_bnode;
   834 
   835     int first_free_edge;
   836 
   837   public:
   838   
   839     class Node {
   840       friend class ListBpUGraphBase;
   841     protected:
   842       int id;
   843 
   844       explicit Node(int _id) : id(_id) {}
   845     public:
   846       Node() {}
   847       Node(Invalid) { id = -1; }
   848       bool operator==(const Node i) const {return id==i.id;}
   849       bool operator!=(const Node i) const {return id!=i.id;}
   850       bool operator<(const Node i) const {return id<i.id;}
   851     };
   852 
   853     class UEdge {
   854       friend class ListBpUGraphBase;
   855     protected:
   856       int id;
   857 
   858       explicit UEdge(int _id) { id = _id;}
   859     public:
   860       UEdge() {}
   861       UEdge (Invalid) { id = -1; }
   862       bool operator==(const UEdge i) const {return id==i.id;}
   863       bool operator!=(const UEdge i) const {return id!=i.id;}
   864       bool operator<(const UEdge i) const {return id<i.id;}
   865     };
   866 
   867     ListBpUGraphBase()
   868       : first_anode(-1), first_free_anode(-1),
   869         first_bnode(-1), first_free_bnode(-1),
   870         first_free_edge(-1) {}
   871 
   872     void firstANode(Node& node) const {
   873       node.id = first_anode != -1 ? (first_anode << 1) : -1;
   874     }
   875     void nextANode(Node& node) const {
   876       node.id = aNodes[node.id >> 1].next;
   877     }
   878 
   879     void firstBNode(Node& node) const {
   880       node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
   881     }
   882     void nextBNode(Node& node) const {
   883       node.id = bNodes[node.id >> 1].next;
   884     }
   885 
   886     void first(Node& node) const {
   887       if (first_anode != -1) {
   888         node.id = (first_anode << 1);
   889       } else if (first_bnode != -1) {
   890         node.id = (first_bnode << 1) + 1;
   891       } else {
   892         node.id = -1;
   893       }
   894     }
   895     void next(Node& node) const {
   896       if (aNode(node)) {
   897         node.id = aNodes[node.id >> 1].next;
   898         if (node.id == -1) {
   899           if (first_bnode != -1) {
   900             node.id = (first_bnode << 1) + 1;
   901           }
   902         }
   903       } else {
   904         node.id = bNodes[node.id >> 1].next;
   905       }
   906     }
   907   
   908     void first(UEdge& edge) const {
   909       int aNodeId = first_anode;
   910       while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
   911         aNodeId = aNodes[aNodeId].next != -1 ? 
   912           aNodes[aNodeId].next >> 1 : -1;
   913       }
   914       if (aNodeId != -1) {
   915         edge.id = aNodes[aNodeId].first_edge;
   916       } else {
   917         edge.id = -1;
   918       }
   919     }
   920     void next(UEdge& edge) const {
   921       int aNodeId = edges[edge.id].aNode >> 1;
   922       edge.id = edges[edge.id].next_out;
   923       if (edge.id == -1) {
   924         aNodeId = aNodes[aNodeId].next != -1 ? 
   925           aNodes[aNodeId].next >> 1 : -1;
   926         while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
   927           aNodeId = aNodes[aNodeId].next != -1 ? 
   928           aNodes[aNodeId].next >> 1 : -1;
   929         }
   930         if (aNodeId != -1) {
   931           edge.id = aNodes[aNodeId].first_edge;
   932         } else {
   933           edge.id = -1;
   934         }
   935       }
   936     }
   937 
   938     void firstFromANode(UEdge& edge, const Node& node) const {
   939       LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
   940       edge.id = aNodes[node.id >> 1].first_edge;
   941     }
   942     void nextFromANode(UEdge& edge) const {
   943       edge.id = edges[edge.id].next_out;
   944     }
   945 
   946     void firstFromBNode(UEdge& edge, const Node& node) const {
   947       LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
   948       edge.id = bNodes[node.id >> 1].first_edge;
   949     }
   950     void nextFromBNode(UEdge& edge) const {
   951       edge.id = edges[edge.id].next_in;
   952     }
   953 
   954     static int id(const Node& node) {
   955       return node.id;
   956     }
   957     static Node nodeFromId(int id) {
   958       return Node(id);
   959     }
   960     int maxNodeId() const {
   961       return aNodes.size() > bNodes.size() ?
   962 	aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
   963     }
   964   
   965     static int id(const UEdge& edge) {
   966       return edge.id;
   967     }
   968     static UEdge uEdgeFromId(int id) {
   969       return UEdge(id);
   970     }
   971     int maxUEdgeId() const {
   972       return edges.size();
   973     }
   974   
   975     static int aNodeId(const Node& node) {
   976       return node.id >> 1;
   977     }
   978     static Node fromANodeId(int id) {
   979       return Node(id << 1);
   980     }
   981     int maxANodeId() const {
   982       return aNodes.size();
   983     }
   984 
   985     static int bNodeId(const Node& node) {
   986       return node.id >> 1;
   987     }
   988     static Node fromBNodeId(int id) {
   989       return Node((id << 1) + 1);
   990     }
   991     int maxBNodeId() const {
   992       return bNodes.size();
   993     }
   994 
   995     Node aNode(const UEdge& edge) const {
   996       return Node(edges[edge.id].aNode);
   997     }
   998     Node bNode(const UEdge& edge) const {
   999       return Node(edges[edge.id].bNode);
  1000     }
  1001 
  1002     static bool aNode(const Node& node) {
  1003       return (node.id & 1) == 0;
  1004     }
  1005 
  1006     static bool bNode(const Node& node) {
  1007       return (node.id & 1) == 1;
  1008     }
  1009 
  1010     Node addANode() {
  1011       int aNodeId;
  1012       if (first_free_anode == -1) {
  1013         aNodeId = aNodes.size();
  1014         aNodes.push_back(NodeT());
  1015       } else {
  1016         aNodeId = first_free_anode;
  1017         first_free_anode = aNodes[first_free_anode].next;
  1018       }
  1019       if (first_anode != -1) {
  1020         aNodes[aNodeId].next = first_anode << 1;
  1021         aNodes[first_anode].prev = aNodeId << 1;
  1022       } else {
  1023         aNodes[aNodeId].next = -1;
  1024       }
  1025       aNodes[aNodeId].prev = -1;
  1026       first_anode = aNodeId;
  1027       aNodes[aNodeId].first_edge = -1;
  1028       return Node(aNodeId << 1);
  1029     }
  1030 
  1031     Node addBNode() {
  1032       int bNodeId;
  1033       if (first_free_bnode == -1) {
  1034         bNodeId = bNodes.size();
  1035         bNodes.push_back(NodeT());
  1036       } else {
  1037         bNodeId = first_free_bnode;
  1038         first_free_bnode = bNodes[first_free_bnode].next;
  1039       }
  1040       if (first_bnode != -1) {
  1041         bNodes[bNodeId].next = (first_bnode << 1) + 1;
  1042         bNodes[first_bnode].prev = (bNodeId << 1) + 1;
  1043       } else {
  1044         bNodes[bNodeId].next = -1;
  1045       }
  1046       first_bnode = bNodeId;
  1047       bNodes[bNodeId].first_edge = -1;
  1048       return Node((bNodeId << 1) + 1);
  1049     }
  1050 
  1051     UEdge addEdge(const Node& source, const Node& target) {
  1052       LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
  1053       int edgeId;
  1054       if (first_free_edge != -1) {
  1055         edgeId = first_free_edge;
  1056         first_free_edge = edges[edgeId].next_out;
  1057       } else {
  1058         edgeId = edges.size();
  1059         edges.push_back(UEdgeT());
  1060       }
  1061       if ((source.id & 1) == 0) {
  1062 	edges[edgeId].aNode = source.id;
  1063 	edges[edgeId].bNode = target.id;
  1064       } else {
  1065 	edges[edgeId].aNode = target.id;
  1066 	edges[edgeId].bNode = source.id;
  1067       }
  1068       edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
  1069       edges[edgeId].prev_out = -1;
  1070       if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
  1071         edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
  1072       }
  1073       aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
  1074       edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
  1075       edges[edgeId].prev_in = -1;
  1076       if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
  1077         edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
  1078       }
  1079       bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
  1080       return UEdge(edgeId);
  1081     }
  1082 
  1083     void erase(const Node& node) {
  1084       if (aNode(node)) {
  1085         int aNodeId = node.id >> 1;
  1086         if (aNodes[aNodeId].prev != -1) {
  1087           aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
  1088         } else {
  1089           first_anode = aNodes[aNodeId].next >> 1;
  1090         }
  1091         if (aNodes[aNodeId].next != -1) {
  1092           aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
  1093         }
  1094         aNodes[aNodeId].next = first_free_anode;
  1095         first_free_anode = aNodeId;
  1096       } else {
  1097         int bNodeId = node.id >> 1;
  1098         if (bNodes[bNodeId].prev != -1) {
  1099           bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
  1100         } else {
  1101           first_bnode = bNodes[bNodeId].next >> 1;
  1102         }
  1103         if (bNodes[bNodeId].next != -1) {
  1104           bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
  1105         }
  1106         bNodes[bNodeId].next = first_free_bnode;
  1107         first_free_bnode = bNodeId;
  1108       }
  1109     }
  1110 
  1111     void erase(const UEdge& edge) {
  1112 
  1113       if (edges[edge.id].prev_out != -1) {
  1114         edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
  1115       } else {
  1116         aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
  1117       }
  1118       if (edges[edge.id].next_out != -1) {
  1119         edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
  1120       }
  1121 
  1122       if (edges[edge.id].prev_in != -1) {
  1123         edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
  1124       } else {
  1125         bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
  1126       }
  1127       if (edges[edge.id].next_in != -1) {
  1128         edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
  1129       }
  1130 
  1131       edges[edge.id].next_out = first_free_edge;
  1132       first_free_edge = edge.id;
  1133     }
  1134 
  1135     void clear() {
  1136       aNodes.clear();
  1137       bNodes.clear();
  1138       edges.clear();
  1139       first_anode = -1;
  1140       first_free_anode = -1;
  1141       first_bnode = -1;
  1142       first_free_bnode = -1;
  1143       first_free_edge = -1;
  1144     }
  1145 
  1146   };
  1147 
  1148 
  1149   typedef BpUGraphExtender< ListBpUGraphBase > ExtendedListBpUGraphBase;
  1150 
  1151   /// \ingroup graphs
  1152   ///
  1153   /// \brief A smart bipartite undirected graph class.
  1154   ///
  1155   /// This is a bipartite undirected graph implementation.
  1156   /// It is conforms to the \ref concept::BpUGraph "BpUGraph concept".
  1157   /// \sa concept::BpUGraph.
  1158   ///
  1159   class ListBpUGraph : public ExtendedListBpUGraphBase {};
  1160 
  1161   
  1162   /// @}  
  1163 } //namespace lemon
  1164   
  1165 
  1166 #endif