COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/list_graph.h @ 2381:0248790c66ea

Last change on this file since 2381:0248790c66ea was 2381:0248790c66ea, checked in by Balazs Dezso, 13 years ago

Bug fix

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