COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/list_graph.h @ 2231:06faf3f06d67

Last change on this file since 2231:06faf3f06d67 was 2231:06faf3f06d67, checked in by Balazs Dezso, 13 years ago

Some rearrangement of concepts and extenders
BpUGraph concepts and concept check test

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