COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/list_graph.h @ 2342:4dd3eb348641

Last change on this file since 2342:4dd3eb348641 was 2342:4dd3eb348641, checked in by Balazs Dezso, 17 years ago

Bug fix

File size: 61.6 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 = getNotifier();
531          Node node;
532          std::vector<Node> nodes;
533          for (notifier->first(node); node != INVALID; notifier->next(node)) {
534            nodes.push_back(node);
535          }
536          for (int i = nodes.size() - 1; i >= 0; --i) {
537            snapshot.addNode(nodes[i]);
538          }
539        }
540        virtual void clear() {
541          NodeNotifier* notifier = getNotifier();
542          Node node;
543          for (notifier->first(node); node != INVALID; notifier->next(node)) {
544            snapshot.eraseNode(node);
545          }
546        }
547
548        Snapshot& snapshot;
549      };
550
551      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
552      public:
553
554        EdgeObserverProxy(Snapshot& _snapshot)
555          : snapshot(_snapshot) {}
556
557        using EdgeNotifier::ObserverBase::attach;
558        using EdgeNotifier::ObserverBase::detach;
559        using EdgeNotifier::ObserverBase::attached;
560       
561      protected:
562
563        virtual void add(const Edge& edge) {
564          snapshot.addEdge(edge);
565        }
566        virtual void add(const std::vector<Edge>& edges) {
567          for (int i = edges.size() - 1; i >= 0; ++i) {
568            snapshot.addEdge(edges[i]);
569          }
570        }
571        virtual void erase(const Edge& edge) {
572          snapshot.eraseEdge(edge);
573        }
574        virtual void erase(const std::vector<Edge>& edges) {
575          for (int i = 0; i < (int)edges.size(); ++i) {
576            snapshot.eraseEdge(edges[i]);
577          }
578        }
579        virtual void build() {
580          EdgeNotifier* notifier = getNotifier();
581          Edge edge;
582          std::vector<Edge> edges;
583          for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
584            edges.push_back(edge);
585          }
586          for (int i = edges.size() - 1; i >= 0; --i) {
587            snapshot.addEdge(edges[i]);
588          }
589        }
590        virtual void clear() {
591          EdgeNotifier* notifier = getNotifier();
592          Edge edge;
593          for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
594            snapshot.eraseEdge(edge);
595          }
596        }
597
598        Snapshot& snapshot;
599      };
600     
601      ListGraph *graph;
602
603      NodeObserverProxy node_observer_proxy;
604      EdgeObserverProxy edge_observer_proxy;
605
606      std::list<Node> added_nodes;
607      std::list<Edge> added_edges;
608
609
610      void addNode(const Node& node) {
611        added_nodes.push_front(node);       
612      }
613      void eraseNode(const Node& node) {
614        std::list<Node>::iterator it =
615          std::find(added_nodes.begin(), added_nodes.end(), node);
616        if (it == added_nodes.end()) {
617          clear();
618          edge_observer_proxy.detach();
619          throw NodeNotifier::ImmediateDetach();
620        } else {
621          added_nodes.erase(it);
622        }
623      }
624
625      void addEdge(const Edge& edge) {
626        added_edges.push_front(edge);       
627      }
628      void eraseEdge(const Edge& edge) {
629        std::list<Edge>::iterator it =
630          std::find(added_edges.begin(), added_edges.end(), edge);
631        if (it == added_edges.end()) {
632          clear();
633          node_observer_proxy.detach();
634          throw EdgeNotifier::ImmediateDetach();
635        } else {
636          added_edges.erase(it);
637        }       
638      }
639
640      void attach(ListGraph &_graph) {
641        graph = &_graph;
642        node_observer_proxy.attach(graph->getNotifier(Node()));
643        edge_observer_proxy.attach(graph->getNotifier(Edge()));
644      }
645           
646      void detach() {
647        node_observer_proxy.detach();
648        edge_observer_proxy.detach();
649      }
650
651      bool attached() const {
652        return node_observer_proxy.attached();
653      }
654
655      void clear() {
656        added_nodes.clear();
657        added_edges.clear();       
658      }
659
660    public:
661
662      /// \brief Default constructor.
663      ///
664      /// Default constructor.
665      /// To actually make a snapshot you must call save().
666      Snapshot()
667        : graph(0), node_observer_proxy(*this),
668          edge_observer_proxy(*this) {}
669     
670      /// \brief Constructor that immediately makes a snapshot.
671      ///     
672      /// This constructor immediately makes a snapshot of the graph.
673      /// \param _graph The graph we make a snapshot of.
674      Snapshot(ListGraph &_graph)
675        : node_observer_proxy(*this),
676          edge_observer_proxy(*this) {
677        attach(_graph);
678      }
679     
680      /// \brief Make a snapshot.
681      ///
682      /// Make a snapshot of the graph.
683      ///
684      /// This function can be called more than once. In case of a repeated
685      /// call, the previous snapshot gets lost.
686      /// \param _graph The graph we make the snapshot of.
687      void save(ListGraph &_graph) {
688        if (attached()) {
689          detach();
690          clear();
691        }
692        attach(_graph);
693      }
694     
695      /// \brief Undo the changes until the last snapshot.
696      //
697      /// Undo the changes until the last snapshot created by save().
698      void restore() {
699        detach();
700        for(std::list<Edge>::iterator it = added_edges.begin();
701            it != added_edges.end(); ++it) {
702          graph->erase(*it);
703        }
704        for(std::list<Node>::iterator it = added_nodes.begin();
705            it != added_nodes.end(); ++it) {
706          graph->erase(*it);
707        }
708        clear();
709      }
710
711      /// \brief Gives back true when the snapshot is valid.
712      ///
713      /// Gives back true when the snapshot is valid.
714      bool valid() const {
715        return attached();
716      }
717    };
718   
719  };
720
721  ///@}
722
723  class ListUGraphBase {
724
725  protected:
726
727    struct NodeT {
728      int first_out;
729      int prev, next;
730    };
731 
732    struct EdgeT {
733      int target;
734      int prev_out, next_out;
735    };
736
737    std::vector<NodeT> nodes;
738
739    int first_node;
740
741    int first_free_node;
742
743    std::vector<EdgeT> edges;
744
745    int first_free_edge;
746   
747  public:
748   
749    typedef ListUGraphBase Graph;
750   
751    class Node {
752      friend class ListUGraphBase;
753    protected:
754
755      int id;
756      explicit Node(int pid) { id = pid;}
757
758    public:
759      Node() {}
760      Node (Invalid) { id = -1; }
761      bool operator==(const Node& node) const {return id == node.id;}
762      bool operator!=(const Node& node) const {return id != node.id;}
763      bool operator<(const Node& node) const {return id < node.id;}
764    };
765
766    class UEdge {
767      friend class ListUGraphBase;
768      friend class ListUGraphBase::Edge;
769    protected:
770
771      int id;
772      explicit UEdge(int pid) { id = pid;}
773
774    public:
775      UEdge() {}
776      UEdge (Invalid) { id = -1; }
777      bool operator==(const UEdge& edge) const {return id == edge.id;}
778      bool operator!=(const UEdge& edge) const {return id != edge.id;}
779      bool operator<(const UEdge& edge) const {return id < edge.id;}
780    };
781
782    class Edge {
783      friend class ListUGraphBase;
784    protected:
785
786      int id;
787      explicit Edge(int pid) { id = pid;}
788
789    public:
790      operator UEdge() const { return UEdge(id / 2); }
791
792      Edge() {}
793      Edge (Invalid) { id = -1; }
794      bool operator==(const Edge& edge) const {return id == edge.id;}
795      bool operator!=(const Edge& edge) const {return id != edge.id;}
796      bool operator<(const Edge& edge) const {return id < edge.id;}
797    };
798
799
800
801    ListUGraphBase()
802      : nodes(), first_node(-1),
803        first_free_node(-1), edges(), first_free_edge(-1) {}
804
805   
806    int maxNodeId() const { return nodes.size()-1; }
807    int maxUEdgeId() const { return edges.size() / 2 - 1; }
808    int maxEdgeId() const { return edges.size()-1; }
809
810    Node source(Edge e) const { return Node(edges[e.id ^ 1].target); }
811    Node target(Edge e) const { return Node(edges[e.id].target); }
812
813    Node source(UEdge e) const { return Node(edges[2 * e.id].target); }
814    Node target(UEdge e) const { return Node(edges[2 * e.id + 1].target); }
815
816    static bool direction(Edge e) {
817      return (e.id & 1) == 1;
818    }
819
820    static Edge direct(UEdge e, bool d) {
821      return Edge(e.id * 2 + (d ? 1 : 0));
822    }
823
824    void first(Node& node) const {
825      node.id = first_node;
826    }
827
828    void next(Node& node) const {
829      node.id = nodes[node.id].next;
830    }
831
832    void first(Edge& e) const {
833      int n = first_node;
834      while (n != -1 && nodes[n].first_out == -1) {
835        n = nodes[n].next;
836      }
837      e.id = (n == -1) ? -1 : nodes[n].first_out;
838    }
839
840    void next(Edge& e) const {
841      if (edges[e.id].next_out != -1) {
842        e.id = edges[e.id].next_out;
843      } else {
844        int n = nodes[edges[e.id ^ 1].target].next;
845        while(n != -1 && nodes[n].first_out == -1) {
846          n = nodes[n].next;
847        }
848        e.id = (n == -1) ? -1 : nodes[n].first_out;
849      }     
850    }
851
852    void first(UEdge& e) const {
853      int n = first_node;
854      while (n != -1) {
855        e.id = nodes[n].first_out;
856        while ((e.id & 1) != 1) {
857          e.id = edges[e.id].next_out;
858        }
859        if (e.id != -1) {
860          e.id /= 2;
861          return;
862        }
863        n = nodes[n].next;
864      }
865      e.id = -1;
866    }
867
868    void next(UEdge& e) const {
869      int n = edges[e.id * 2].target;
870      e.id = edges[(e.id * 2) | 1].next_out;
871      while ((e.id & 1) != 1) {
872        e.id = edges[e.id].next_out;
873      }
874      if (e.id != -1) {
875        e.id /= 2;
876        return;
877      }
878      n = nodes[n].next;
879      while (n != -1) {
880        e.id = nodes[n].first_out;
881        while ((e.id & 1) != 1) {
882          e.id = edges[e.id].next_out;
883        }
884        if (e.id != -1) {
885          e.id /= 2;
886          return;
887        }
888        n = nodes[n].next;
889      }
890      e.id = -1;
891    }
892
893    void firstOut(Edge &e, const Node& v) const {
894      e.id = nodes[v.id].first_out;
895    }
896    void nextOut(Edge &e) const {
897      e.id = edges[e.id].next_out;
898    }
899
900    void firstIn(Edge &e, const Node& v) const {
901      e.id = ((nodes[v.id].first_out) ^ 1);
902      if (e.id == -2) e.id = -1;
903    }
904    void nextIn(Edge &e) const {
905      e.id = ((edges[e.id ^ 1].next_out) ^ 1);
906      if (e.id == -2) e.id = -1;
907    }
908
909    void firstInc(UEdge &e, bool& d, const Node& v) const {
910      int de = nodes[v.id].first_out;
911      e.id = de / 2;
912      d = ((de & 1) == 1);
913    }
914    void nextInc(UEdge &e, bool& d) const {
915      int de = (edges[(e.id * 2) | (d ? 1 : 0)].next_out);
916      e.id = de / 2;
917      d = ((de & 1) == 1);
918    }
919   
920    static int id(Node v) { return v.id; }
921    static int id(Edge e) { return e.id; }
922    static int id(UEdge e) { return e.id; }
923
924    static Node nodeFromId(int id) { return Node(id);}
925    static Edge edgeFromId(int id) { return Edge(id);}
926    static UEdge uEdgeFromId(int id) { return UEdge(id);}
927
928    Node addNode() {     
929      int n;
930     
931      if(first_free_node==-1) {
932        n = nodes.size();
933        nodes.push_back(NodeT());
934      } else {
935        n = first_free_node;
936        first_free_node = nodes[n].next;
937      }
938     
939      nodes[n].next = first_node;
940      if (first_node != -1) nodes[first_node].prev = n;
941      first_node = n;
942      nodes[n].prev = -1;
943     
944      nodes[n].first_out = -1;
945     
946      return Node(n);
947    }
948   
949    UEdge addEdge(Node u, Node v) {
950      int n;     
951
952      if (first_free_edge == -1) {
953        n = edges.size();
954        edges.push_back(EdgeT());
955        edges.push_back(EdgeT());
956      } else {
957        n = first_free_edge;
958        first_free_edge = edges[n].next_out;
959      }
960     
961      edges[n].target = u.id;
962      edges[n | 1].target = v.id;
963
964      edges[n].next_out = nodes[v.id].first_out;
965      edges[n | 1].next_out = nodes[u.id].first_out;
966      if (nodes[v.id].first_out != -1) {
967        edges[nodes[v.id].first_out].prev_out = n;
968      }
969      if (nodes[u.id].first_out != -1) {
970        edges[nodes[u.id].first_out].prev_out = (n | 1);
971      }
972     
973      edges[n].prev_out = edges[n | 1].prev_out = -1;
974       
975      nodes[v.id].first_out = n;
976      nodes[u.id].first_out = (n | 1);
977
978      return UEdge(n / 2);
979    }
980   
981    void erase(const Node& node) {
982      int n = node.id;
983     
984      if(nodes[n].next != -1) {
985        nodes[nodes[n].next].prev = nodes[n].prev;
986      }
987     
988      if(nodes[n].prev != -1) {
989        nodes[nodes[n].prev].next = nodes[n].next;
990      } else {
991        first_node = nodes[n].next;
992      }
993     
994      nodes[n].next = first_free_node;
995      first_free_node = n;
996
997    }
998   
999    void erase(const UEdge& edge) {
1000      int n = edge.id * 2;
1001     
1002      if (edges[n].next_out != -1) {
1003        edges[edges[n].next_out].prev_out = edges[n].prev_out;
1004      }
1005
1006      if (edges[n].prev_out != -1) {
1007        edges[edges[n].prev_out].next_out = edges[n].next_out;
1008      } else {
1009        nodes[edges[n | 1].target].first_out = edges[n].next_out;
1010      }
1011
1012      if (edges[n | 1].next_out != -1) {
1013        edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
1014      }
1015
1016      if (edges[n | 1].prev_out != -1) {
1017        edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
1018      } else {
1019        nodes[edges[n].target].first_out = edges[n | 1].next_out;
1020      }
1021     
1022      edges[n].next_out = first_free_edge;
1023      first_free_edge = n;     
1024
1025    }
1026
1027    void clear() {
1028      edges.clear();
1029      nodes.clear();
1030      first_node = first_free_node = first_free_edge = -1;
1031    }
1032
1033  protected:
1034
1035    void changeTarget(UEdge e, Node n) {
1036      if(edges[2 * e.id].next_out != -1) {
1037        edges[edges[2 * e.id].next_out].prev_out = edges[2 * e.id].prev_out;
1038      }
1039      if(edges[2 * e.id].prev_out != -1) {
1040        edges[edges[2 * e.id].prev_out].next_out =
1041          edges[2 * e.id].next_out;
1042      } else {
1043        nodes[edges[(2 * e.id) | 1].target].first_out =
1044          edges[2 * e.id].next_out;
1045      }
1046
1047      if (nodes[n.id].first_out != -1) {
1048        edges[nodes[n.id].first_out].prev_out = 2 * e.id;
1049      }
1050      edges[(2 * e.id) | 1].target = n.id;
1051      edges[2 * e.id].prev_out = -1;
1052      edges[2 * e.id].next_out = nodes[n.id].first_out;
1053      nodes[n.id].first_out = 2 * e.id;
1054    }
1055
1056    void changeSource(UEdge e, Node n) {
1057      if(edges[(2 * e.id) | 1].next_out != -1) {
1058        edges[edges[(2 * e.id) | 1].next_out].prev_out =
1059          edges[(2 * e.id) | 1].prev_out;
1060      }
1061      if(edges[(2 * e.id) | 1].prev_out != -1) {
1062        edges[edges[(2 * e.id) | 1].prev_out].next_out =
1063          edges[(2 * e.id) | 1].next_out;
1064      } else {
1065        nodes[edges[2 * e.id].target].first_out =
1066          edges[(2 * e.id) | 1].next_out;
1067      }
1068
1069      if (nodes[n.id].first_out != -1) {
1070        edges[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1071      }
1072      edges[2 * e.id].target = n.id;
1073      edges[(2 * e.id) | 1].prev_out = -1;
1074      edges[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1075      nodes[n.id].first_out = ((2 * e.id) | 1);
1076    }
1077
1078  };
1079
1080//   typedef UGraphExtender<UndirGraphExtender<ListGraphBase> >
1081//   ExtendedListUGraphBase;
1082
1083  typedef UGraphExtender<ListUGraphBase> ExtendedListUGraphBase;
1084
1085
1086
1087  /// \addtogroup graphs
1088  /// @{
1089
1090  ///An undirected list graph class.
1091
1092  ///This is a simple and fast undirected graph implementation.
1093  ///
1094  ///An important extra feature of this graph implementation is that
1095  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1096  ///
1097  ///It conforms to the
1098  ///\ref concepts::UGraph "UGraph concept".
1099  ///
1100  ///\sa concepts::UGraph.
1101  ///
1102  class ListUGraph : public ExtendedListUGraphBase {
1103  private:
1104    ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
1105
1106    ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
1107    ///
1108    ListUGraph(const ListUGraph &) :ExtendedListUGraphBase()  {};
1109    ///\brief Assignment of ListUGraph to another one is \e not allowed.
1110    ///Use UGraphCopy() instead.
1111
1112    ///Assignment of ListUGraph to another one is \e not allowed.
1113    ///Use UGraphCopy() instead.
1114    void operator=(const ListUGraph &) {}
1115  public:
1116    /// Constructor
1117   
1118    /// Constructor.
1119    ///
1120    ListUGraph() {}
1121
1122    typedef ExtendedListUGraphBase Parent;
1123
1124    typedef Parent::OutEdgeIt IncEdgeIt;
1125
1126    /// \brief Add a new node to the graph.
1127    ///
1128    /// \return the new node.
1129    ///
1130    Node addNode() { return Parent::addNode(); }
1131
1132    /// \brief Add a new edge to the graph.
1133    ///
1134    /// Add a new edge to the graph with source node \c s
1135    /// and target node \c t.
1136    /// \return the new undirected edge.
1137    UEdge addEdge(const Node& s, const Node& t) {
1138      return Parent::addEdge(s, t);
1139    }
1140    /// \brief Changes the source of \c e to \c n
1141    ///
1142    /// Changes the source of \c e to \c n
1143    ///
1144    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
1145    ///referencing the changed edge remain
1146    ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
1147    void changeSource(UEdge e, Node n) {
1148      Parent::changeSource(e,n);
1149    }   
1150    /// \brief Changes the target of \c e to \c n
1151    ///
1152    /// Changes the target of \c e to \c n
1153    ///
1154    /// \note The <tt>EdgeIt</tt>s referencing the changed edge remain
1155    /// valid. However the other iterators may be invalidated.
1156    void changeTarget(UEdge e, Node n) {
1157      Parent::changeTarget(e,n);
1158    }
1159    /// \brief Changes the source of \c e to \c n
1160    ///
1161    /// Changes the source of \c e to \c n. It changes the proper
1162    /// node of the represented undirected edge.
1163    ///
1164    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
1165    ///referencing the changed edge remain
1166    ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
1167    void changeSource(Edge e, Node n) {
1168      if (Parent::direction(e)) {
1169        Parent::changeSource(e,n);
1170      } else {
1171        Parent::changeTarget(e,n);
1172      }
1173    }
1174    /// \brief Changes the target of \c e to \c n
1175    ///
1176    /// Changes the target of \c e to \c n. It changes the proper
1177    /// node of the represented undirected edge.
1178    ///
1179    ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1180    ///referencing the changed edge remain
1181    ///valid. However <tt>InEdgeIt</tt>s are invalidated.
1182    void changeTarget(Edge e, Node n) {
1183      if (Parent::direction(e)) {
1184        Parent::changeTarget(e,n);
1185      } else {
1186        Parent::changeSource(e,n);
1187      }
1188    }
1189    /// \brief Contract two nodes.
1190    ///
1191    /// This function contracts two nodes.
1192    ///
1193    /// Node \p b will be removed but instead of deleting
1194    /// its neighboring edges, they will be joined to \p a.
1195    /// The last parameter \p r controls whether to remove loops. \c true
1196    /// means that loops will be removed.
1197    ///
1198    /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
1199    /// valid.
1200    void contract(Node a, Node b, bool r = true) {
1201      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1202        IncEdgeIt f = e; ++f;
1203        if (r && runningNode(e) == a) {
1204          erase(e);
1205        } else if (source(e) == b) {
1206          changeSource(e, a);
1207        } else {
1208          changeTarget(e, a);
1209        }
1210        e = f;
1211      }
1212      erase(b);
1213    }
1214
1215
1216    /// \brief Class to make a snapshot of the graph and restore
1217    /// to it later.
1218    ///
1219    /// Class to make a snapshot of the graph and to restore it
1220    /// later.
1221    ///
1222    /// The newly added nodes and undirected edges can be removed
1223    /// using the restore() function.
1224    ///
1225    /// \warning Edge and node deletions cannot be restored. This
1226    /// events invalidate the snapshot.
1227    class Snapshot {
1228    protected:
1229
1230      typedef Parent::NodeNotifier NodeNotifier;
1231
1232      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1233      public:
1234
1235        NodeObserverProxy(Snapshot& _snapshot)
1236          : snapshot(_snapshot) {}
1237
1238        using NodeNotifier::ObserverBase::attach;
1239        using NodeNotifier::ObserverBase::detach;
1240        using NodeNotifier::ObserverBase::attached;
1241       
1242      protected:
1243       
1244        virtual void add(const Node& node) {
1245          snapshot.addNode(node);
1246        }
1247        virtual void add(const std::vector<Node>& nodes) {
1248          for (int i = nodes.size() - 1; i >= 0; ++i) {
1249            snapshot.addNode(nodes[i]);
1250          }
1251        }
1252        virtual void erase(const Node& node) {
1253          snapshot.eraseNode(node);
1254        }
1255        virtual void erase(const std::vector<Node>& nodes) {
1256          for (int i = 0; i < (int)nodes.size(); ++i) {
1257            snapshot.eraseNode(nodes[i]);
1258          }
1259        }
1260        virtual void build() {
1261          NodeNotifier* notifier = getNotifier();
1262          Node node;
1263          std::vector<Node> nodes;
1264          for (notifier->first(node); node != INVALID; notifier->next(node)) {
1265            nodes.push_back(node);
1266          }
1267          for (int i = nodes.size() - 1; i >= 0; --i) {
1268            snapshot.addNode(nodes[i]);
1269          }
1270        }
1271        virtual void clear() {
1272          NodeNotifier* notifier = getNotifier();
1273          Node node;
1274          for (notifier->first(node); node != INVALID; notifier->next(node)) {
1275            snapshot.eraseNode(node);
1276          }
1277        }
1278
1279        Snapshot& snapshot;
1280      };
1281
1282      class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
1283      public:
1284
1285        UEdgeObserverProxy(Snapshot& _snapshot)
1286          : snapshot(_snapshot) {}
1287
1288        using UEdgeNotifier::ObserverBase::attach;
1289        using UEdgeNotifier::ObserverBase::detach;
1290        using UEdgeNotifier::ObserverBase::attached;
1291       
1292      protected:
1293
1294        virtual void add(const UEdge& edge) {
1295          snapshot.addUEdge(edge);
1296        }
1297        virtual void add(const std::vector<UEdge>& edges) {
1298          for (int i = edges.size() - 1; i >= 0; ++i) {
1299            snapshot.addUEdge(edges[i]);
1300          }
1301        }
1302        virtual void erase(const UEdge& edge) {
1303          snapshot.eraseUEdge(edge);
1304        }
1305        virtual void erase(const std::vector<UEdge>& edges) {
1306          for (int i = 0; i < (int)edges.size(); ++i) {
1307            snapshot.eraseUEdge(edges[i]);
1308          }
1309        }
1310        virtual void build() {
1311          UEdgeNotifier* notifier = getNotifier();
1312          UEdge edge;
1313          std::vector<UEdge> edges;
1314          for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
1315            edges.push_back(edge);
1316          }
1317          for (int i = edges.size() - 1; i >= 0; --i) {
1318            snapshot.addUEdge(edges[i]);
1319          }
1320        }
1321        virtual void clear() {
1322          UEdgeNotifier* notifier = getNotifier();
1323          UEdge edge;
1324          for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
1325            snapshot.eraseUEdge(edge);
1326          }
1327        }
1328
1329        Snapshot& snapshot;
1330      };
1331     
1332      ListUGraph *graph;
1333
1334      NodeObserverProxy node_observer_proxy;
1335      UEdgeObserverProxy edge_observer_proxy;
1336
1337      std::list<Node> added_nodes;
1338      std::list<UEdge> added_edges;
1339
1340
1341      void addNode(const Node& node) {
1342        added_nodes.push_front(node);       
1343      }
1344      void eraseNode(const Node& node) {
1345        std::list<Node>::iterator it =
1346          std::find(added_nodes.begin(), added_nodes.end(), node);
1347        if (it == added_nodes.end()) {
1348          clear();
1349          edge_observer_proxy.detach();
1350          throw NodeNotifier::ImmediateDetach();
1351        } else {
1352          added_nodes.erase(it);
1353        }
1354      }
1355
1356      void addUEdge(const UEdge& edge) {
1357        added_edges.push_front(edge);       
1358      }
1359      void eraseUEdge(const UEdge& edge) {
1360        std::list<UEdge>::iterator it =
1361          std::find(added_edges.begin(), added_edges.end(), edge);
1362        if (it == added_edges.end()) {
1363          clear();
1364          node_observer_proxy.detach();
1365          throw UEdgeNotifier::ImmediateDetach();
1366        } else {
1367          added_edges.erase(it);
1368        }       
1369      }
1370
1371      void attach(ListUGraph &_graph) {
1372        graph = &_graph;
1373        node_observer_proxy.attach(graph->getNotifier(Node()));
1374        edge_observer_proxy.attach(graph->getNotifier(UEdge()));
1375      }
1376           
1377      void detach() {
1378        node_observer_proxy.detach();
1379        edge_observer_proxy.detach();
1380      }
1381
1382      bool attached() const {
1383        return node_observer_proxy.attached();
1384      }
1385
1386      void clear() {
1387        added_nodes.clear();
1388        added_edges.clear();       
1389      }
1390
1391    public:
1392
1393      /// \brief Default constructor.
1394      ///
1395      /// Default constructor.
1396      /// To actually make a snapshot you must call save().
1397      Snapshot()
1398        : graph(0), node_observer_proxy(*this),
1399          edge_observer_proxy(*this) {}
1400     
1401      /// \brief Constructor that immediately makes a snapshot.
1402      ///     
1403      /// This constructor immediately makes a snapshot of the graph.
1404      /// \param _graph The graph we make a snapshot of.
1405      Snapshot(ListUGraph &_graph)
1406        : node_observer_proxy(*this),
1407          edge_observer_proxy(*this) {
1408        attach(_graph);
1409      }
1410     
1411      /// \brief Make a snapshot.
1412      ///
1413      /// Make a snapshot of the graph.
1414      ///
1415      /// This function can be called more than once. In case of a repeated
1416      /// call, the previous snapshot gets lost.
1417      /// \param _graph The graph we make the snapshot of.
1418      void save(ListUGraph &_graph) {
1419        if (attached()) {
1420          detach();
1421          clear();
1422        }
1423        attach(_graph);
1424      }
1425     
1426      /// \brief Undo the changes until the last snapshot.
1427      //
1428      /// Undo the changes until the last snapshot created by save().
1429      void restore() {
1430        detach();
1431        for(std::list<UEdge>::iterator it = added_edges.begin();
1432            it != added_edges.end(); ++it) {
1433          graph->erase(*it);
1434        }
1435        for(std::list<Node>::iterator it = added_nodes.begin();
1436            it != added_nodes.end(); ++it) {
1437          graph->erase(*it);
1438        }
1439        clear();
1440      }
1441
1442      /// \brief Gives back true when the snapshot is valid.
1443      ///
1444      /// Gives back true when the snapshot is valid.
1445      bool valid() const {
1446        return attached();
1447      }
1448    };
1449  };
1450
1451
1452  class ListBpUGraphBase {
1453  public:
1454
1455    class NodeSetError : public LogicError {
1456    public:
1457      virtual const char* what() const throw() {
1458        return "lemon::ListBpUGraph::NodeSetError";
1459      }
1460    };
1461
1462  protected:
1463
1464    struct NodeT {
1465      int first_edge, prev, next;
1466    };
1467
1468    struct UEdgeT {
1469      int aNode, prev_out, next_out;
1470      int bNode, prev_in, next_in;
1471    };
1472
1473    std::vector<NodeT> aNodes;
1474    std::vector<NodeT> bNodes;
1475
1476    std::vector<UEdgeT> edges;
1477
1478    int first_anode;
1479    int first_free_anode;
1480
1481    int first_bnode;
1482    int first_free_bnode;
1483
1484    int first_free_edge;
1485
1486  public:
1487 
1488    class Node {
1489      friend class ListBpUGraphBase;
1490    protected:
1491      int id;
1492
1493      explicit Node(int _id) : id(_id) {}
1494    public:
1495      Node() {}
1496      Node(Invalid) { id = -1; }
1497      bool operator==(const Node i) const {return id==i.id;}
1498      bool operator!=(const Node i) const {return id!=i.id;}
1499      bool operator<(const Node i) const {return id<i.id;}
1500    };
1501
1502    class UEdge {
1503      friend class ListBpUGraphBase;
1504    protected:
1505      int id;
1506
1507      explicit UEdge(int _id) { id = _id;}
1508    public:
1509      UEdge() {}
1510      UEdge (Invalid) { id = -1; }
1511      bool operator==(const UEdge i) const {return id==i.id;}
1512      bool operator!=(const UEdge i) const {return id!=i.id;}
1513      bool operator<(const UEdge i) const {return id<i.id;}
1514    };
1515
1516    ListBpUGraphBase()
1517      : first_anode(-1), first_free_anode(-1),
1518        first_bnode(-1), first_free_bnode(-1),
1519        first_free_edge(-1) {}
1520
1521    void firstANode(Node& node) const {
1522      node.id = first_anode != -1 ? (first_anode << 1) : -1;
1523    }
1524    void nextANode(Node& node) const {
1525      node.id = aNodes[node.id >> 1].next;
1526    }
1527
1528    void firstBNode(Node& node) const {
1529      node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
1530    }
1531    void nextBNode(Node& node) const {
1532      node.id = bNodes[node.id >> 1].next;
1533    }
1534
1535    void first(Node& node) const {
1536      if (first_anode != -1) {
1537        node.id = (first_anode << 1);
1538      } else if (first_bnode != -1) {
1539        node.id = (first_bnode << 1) + 1;
1540      } else {
1541        node.id = -1;
1542      }
1543    }
1544    void next(Node& node) const {
1545      if (aNode(node)) {
1546        node.id = aNodes[node.id >> 1].next;
1547        if (node.id == -1) {
1548          if (first_bnode != -1) {
1549            node.id = (first_bnode << 1) + 1;
1550          }
1551        }
1552      } else {
1553        node.id = bNodes[node.id >> 1].next;
1554      }
1555    }
1556 
1557    void first(UEdge& edge) const {
1558      int aNodeId = first_anode;
1559      while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
1560        aNodeId = aNodes[aNodeId].next != -1 ?
1561          aNodes[aNodeId].next >> 1 : -1;
1562      }
1563      if (aNodeId != -1) {
1564        edge.id = aNodes[aNodeId].first_edge;
1565      } else {
1566        edge.id = -1;
1567      }
1568    }
1569    void next(UEdge& edge) const {
1570      int aNodeId = edges[edge.id].aNode >> 1;
1571      edge.id = edges[edge.id].next_out;
1572      if (edge.id == -1) {
1573        aNodeId = aNodes[aNodeId].next != -1 ?
1574          aNodes[aNodeId].next >> 1 : -1;
1575        while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
1576          aNodeId = aNodes[aNodeId].next != -1 ?
1577          aNodes[aNodeId].next >> 1 : -1;
1578        }
1579        if (aNodeId != -1) {
1580          edge.id = aNodes[aNodeId].first_edge;
1581        } else {
1582          edge.id = -1;
1583        }
1584      }
1585    }
1586
1587    void firstFromANode(UEdge& edge, const Node& node) const {
1588      LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
1589      edge.id = aNodes[node.id >> 1].first_edge;
1590    }
1591    void nextFromANode(UEdge& edge) const {
1592      edge.id = edges[edge.id].next_out;
1593    }
1594
1595    void firstFromBNode(UEdge& edge, const Node& node) const {
1596      LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
1597      edge.id = bNodes[node.id >> 1].first_edge;
1598    }
1599    void nextFromBNode(UEdge& edge) const {
1600      edge.id = edges[edge.id].next_in;
1601    }
1602
1603    static int id(const Node& node) {
1604      return node.id;
1605    }
1606    static Node nodeFromId(int id) {
1607      return Node(id);
1608    }
1609    int maxNodeId() const {
1610      return aNodes.size() > bNodes.size() ?
1611        aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
1612    }
1613 
1614    static int id(const UEdge& edge) {
1615      return edge.id;
1616    }
1617    static UEdge uEdgeFromId(int id) {
1618      return UEdge(id);
1619    }
1620    int maxUEdgeId() const {
1621      return edges.size();
1622    }
1623 
1624    static int aNodeId(const Node& node) {
1625      return node.id >> 1;
1626    }
1627    static Node nodeFromANodeId(int id) {
1628      return Node(id << 1);
1629    }
1630    int maxANodeId() const {
1631      return aNodes.size();
1632    }
1633
1634    static int bNodeId(const Node& node) {
1635      return node.id >> 1;
1636    }
1637    static Node nodeFromBNodeId(int id) {
1638      return Node((id << 1) + 1);
1639    }
1640    int maxBNodeId() const {
1641      return bNodes.size();
1642    }
1643
1644    Node aNode(const UEdge& edge) const {
1645      return Node(edges[edge.id].aNode);
1646    }
1647    Node bNode(const UEdge& edge) const {
1648      return Node(edges[edge.id].bNode);
1649    }
1650
1651    static bool aNode(const Node& node) {
1652      return (node.id & 1) == 0;
1653    }
1654
1655    static bool bNode(const Node& node) {
1656      return (node.id & 1) == 1;
1657    }
1658
1659    Node addANode() {
1660      int aNodeId;
1661      if (first_free_anode == -1) {
1662        aNodeId = aNodes.size();
1663        aNodes.push_back(NodeT());
1664      } else {
1665        aNodeId = first_free_anode;
1666        first_free_anode = aNodes[first_free_anode].next;
1667      }
1668      if (first_anode != -1) {
1669        aNodes[aNodeId].next = first_anode << 1;
1670        aNodes[first_anode].prev = aNodeId << 1;
1671      } else {
1672        aNodes[aNodeId].next = -1;
1673      }
1674      aNodes[aNodeId].prev = -1;
1675      first_anode = aNodeId;
1676      aNodes[aNodeId].first_edge = -1;
1677      return Node(aNodeId << 1);
1678    }
1679
1680    Node addBNode() {
1681      int bNodeId;
1682      if (first_free_bnode == -1) {
1683        bNodeId = bNodes.size();
1684        bNodes.push_back(NodeT());
1685      } else {
1686        bNodeId = first_free_bnode;
1687        first_free_bnode = bNodes[first_free_bnode].next;
1688      }
1689      if (first_bnode != -1) {
1690        bNodes[bNodeId].next = (first_bnode << 1) + 1;
1691        bNodes[first_bnode].prev = (bNodeId << 1) + 1;
1692      } else {
1693        bNodes[bNodeId].next = -1;
1694      }
1695      bNodes[bNodeId].prev = -1;
1696      first_bnode = bNodeId;
1697      bNodes[bNodeId].first_edge = -1;
1698      return Node((bNodeId << 1) + 1);
1699    }
1700
1701    UEdge addEdge(const Node& source, const Node& target) {
1702      LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
1703      int edgeId;
1704      if (first_free_edge != -1) {
1705        edgeId = first_free_edge;
1706        first_free_edge = edges[edgeId].next_out;
1707      } else {
1708        edgeId = edges.size();
1709        edges.push_back(UEdgeT());
1710      }
1711      if ((source.id & 1) == 0) {
1712        edges[edgeId].aNode = source.id;
1713        edges[edgeId].bNode = target.id;
1714      } else {
1715        edges[edgeId].aNode = target.id;
1716        edges[edgeId].bNode = source.id;
1717      }
1718      edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
1719      edges[edgeId].prev_out = -1;
1720      if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
1721        edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
1722      }
1723      aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
1724      edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
1725      edges[edgeId].prev_in = -1;
1726      if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
1727        edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
1728      }
1729      bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
1730      return UEdge(edgeId);
1731    }
1732
1733    void erase(const Node& node) {
1734      if (aNode(node)) {
1735        int aNodeId = node.id >> 1;
1736        if (aNodes[aNodeId].prev != -1) {
1737          aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
1738        } else {
1739          first_anode =
1740            aNodes[aNodeId].next != -1 ? aNodes[aNodeId].next >> 1 : -1;
1741        }
1742        if (aNodes[aNodeId].next != -1) {
1743          aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
1744        }
1745        aNodes[aNodeId].next = first_free_anode;
1746        first_free_anode = aNodeId;
1747      } else {
1748        int bNodeId = node.id >> 1;
1749        if (bNodes[bNodeId].prev != -1) {
1750          bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
1751        } else {
1752          first_bnode =
1753            bNodes[bNodeId].next != -1 ? bNodes[bNodeId].next >> 1 : -1;
1754        }
1755        if (bNodes[bNodeId].next != -1) {
1756          bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
1757        }
1758        bNodes[bNodeId].next = first_free_bnode;
1759        first_free_bnode = bNodeId;
1760      }
1761    }
1762
1763    void erase(const UEdge& edge) {
1764
1765      if (edges[edge.id].prev_out != -1) {
1766        edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
1767      } else {
1768        aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
1769      }
1770      if (edges[edge.id].next_out != -1) {
1771        edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
1772      }
1773
1774      if (edges[edge.id].prev_in != -1) {
1775        edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
1776      } else {
1777        bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
1778      }
1779      if (edges[edge.id].next_in != -1) {
1780        edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
1781      }
1782
1783      edges[edge.id].next_out = first_free_edge;
1784      first_free_edge = edge.id;
1785    }
1786 
1787    void clear() {
1788      aNodes.clear();
1789      bNodes.clear();
1790      edges.clear();
1791      first_anode = -1;
1792      first_free_anode = -1;
1793      first_bnode = -1;
1794      first_free_bnode = -1;
1795      first_free_edge = -1;
1796    }
1797
1798    void changeANode(const UEdge& edge, const Node& node) {
1799      LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
1800      if (edges[edge.id].prev_out != -1) {
1801        edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
1802      } else {
1803        aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
1804      }
1805      if (edges[edge.id].next_out != -1) {
1806        edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out; 
1807      }
1808      if (aNodes[node.id >> 1].first_edge != -1) {
1809        edges[aNodes[node.id >> 1].first_edge].prev_out = edge.id;
1810      }
1811      edges[edge.id].prev_out = -1;
1812      edges[edge.id].next_out = aNodes[node.id >> 1].first_edge;
1813      aNodes[node.id >> 1].first_edge = edge.id;
1814      edges[edge.id].aNode = node.id;
1815    }
1816
1817    void changeBNode(const UEdge& edge, const Node& node) {
1818      LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
1819      if (edges[edge.id].prev_in != -1) {
1820        edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
1821      } else {
1822        bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
1823      }
1824      if (edges[edge.id].next_in != -1) {
1825        edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in; 
1826      }
1827      if (bNodes[node.id >> 1].first_edge != -1) {
1828        edges[bNodes[node.id >> 1].first_edge].prev_in = edge.id;
1829      }
1830      edges[edge.id].prev_in = -1;
1831      edges[edge.id].next_in = bNodes[node.id >> 1].first_edge;
1832      bNodes[node.id >> 1].first_edge = edge.id;
1833      edges[edge.id].bNode = node.id;
1834    }
1835
1836  };
1837
1838
1839  typedef BpUGraphExtender<BidirBpUGraphExtender<ListBpUGraphBase> >
1840  ExtendedListBpUGraphBase;
1841
1842  /// \ingroup graphs
1843  ///
1844  /// \brief A smart bipartite undirected graph class.
1845  ///
1846  /// This is a bipartite undirected graph implementation.
1847  /// It is conforms to the \ref concepts::BpUGraph "BpUGraph concept".
1848  ///
1849  ///An important extra feature of this graph implementation is that
1850  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1851  ///
1852  /// \sa concepts::BpUGraph.
1853  ///
1854  class ListBpUGraph : public ExtendedListBpUGraphBase {
1855    /// \brief ListBpUGraph is \e not copy constructible.
1856    ///
1857    ///ListBpUGraph is \e not copy constructible.
1858    ListBpUGraph(const ListBpUGraph &) :ExtendedListBpUGraphBase()  {};
1859    /// \brief Assignment of ListBpUGraph to another one is \e not
1860    /// allowed.
1861    ///
1862    /// Assignment of ListBpUGraph to another one is \e not allowed.
1863    void operator=(const ListBpUGraph &) {}
1864  public:
1865    /// \brief Constructor
1866    ///   
1867    /// Constructor.
1868    ///
1869    ListBpUGraph() {}
1870
1871    typedef ExtendedListBpUGraphBase Parent;
1872    /// \brief Add a new ANode to the graph.
1873    ///
1874    /// \return the new node.
1875    ///
1876    Node addANode() { return Parent::addANode(); }
1877
1878    /// \brief Add a new BNode to the graph.
1879    ///
1880    /// \return the new node.
1881    ///
1882    Node addBNode() { return Parent::addBNode(); }
1883
1884    /// \brief Add a new edge to the graph.
1885    ///
1886    /// Add a new edge to the graph with an ANode and a BNode.
1887    /// \return the new undirected edge.
1888    UEdge addEdge(const Node& s, const Node& t) {
1889      return Parent::addEdge(s, t);
1890    }
1891
1892    /// \brief Changes the ANode of \c e to \c n
1893    ///
1894    /// Changes the ANode of \c e to \c n
1895    ///
1896    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
1897    ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
1898    ///invalidated.
1899    void changeANode(UEdge e, Node n) {
1900      Parent::changeANode(e,n);
1901    }
1902
1903    /// \brief Changes the BNode of \c e to \c n
1904    ///
1905    /// Changes the BNode of \c e to \c n
1906    ///
1907    /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1908    /// referencing the changed edge remain
1909    /// valid. However <tt>InEdgeIt</tt>s are invalidated.
1910    void changeBNode(UEdge e, Node n) {
1911      Parent::changeBNode(e,n);
1912    }
1913
1914    /// \brief Changes the source(ANode) of \c e to \c n
1915    ///
1916    /// Changes the source(ANode) of \c e to \c n
1917    ///
1918    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
1919    ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
1920    ///invalidated.
1921    void changeSource(UEdge e, Node n) {
1922      Parent::changeANode(e,n);
1923    }
1924
1925    /// \brief Changes the target(BNode) of \c e to \c n
1926    ///
1927    /// Changes the target(BNode) of \c e to \c n
1928    ///
1929    /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1930    /// referencing the changed edge remain
1931    /// valid. However <tt>InEdgeIt</tt>s are invalidated.
1932    void changeTarget(UEdge e, Node n) {
1933      Parent::changeBNode(e,n);
1934    }
1935
1936    /// \brief Changes the source of \c e to \c n
1937    ///
1938    /// Changes the source of \c e to \c n. It changes the proper
1939    /// node of the represented undirected edge.
1940    ///
1941    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
1942    ///referencing the changed edge remain
1943    ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
1944    void changeSource(Edge e, Node n) {
1945      if (Parent::direction(e)) {
1946        Parent::changeANode(e,n);
1947      } else {
1948        Parent::changeBNode(e,n);
1949      }
1950    }
1951    /// \brief Changes the target of \c e to \c n
1952    ///
1953    /// Changes the target of \c e to \c n. It changes the proper
1954    /// node of the represented undirected edge.
1955    ///
1956    ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1957    ///referencing the changed edge remain
1958    ///valid. However <tt>InEdgeIt</tt>s are invalidated.
1959    void changeTarget(Edge e, Node n) {
1960      if (Parent::direction(e)) {
1961        Parent::changeBNode(e,n);
1962      } else {
1963        Parent::changeANode(e,n);
1964      }
1965    }
1966    /// \brief Contract two nodes.
1967    ///
1968    /// This function contracts two nodes.
1969    ///
1970    /// Node \p b will be removed but instead of deleting its
1971    /// neighboring edges, they will be joined to \p a.  The two nodes
1972    /// should be from the same nodeset, of course.
1973    ///
1974    /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
1975    /// valid.
1976    void contract(const Node& a, const Node& b) {
1977      LEMON_ASSERT(Parent::aNode(a) == Parent::aNode(b), NodeSetError());
1978      if (Parent::aNode(a)) {
1979        for (IncEdgeIt e(*this, b); e!=INVALID;) {
1980          IncEdgeIt f = e; ++f;
1981          changeSource(e, a);
1982          e = f;
1983        }
1984      } else {
1985        for (IncEdgeIt e(*this, b); e!=INVALID;) {
1986          IncEdgeIt f = e; ++f;
1987          changeTarget(e, a);
1988          e = f;
1989        }
1990      }
1991      erase(b);
1992    }
1993
1994    /// \brief Class to make a snapshot of the graph and restore
1995    /// to it later.
1996    ///
1997    /// Class to make a snapshot of the graph and to restore it
1998    /// later.
1999    ///
2000    /// The newly added nodes and undirected edges can be removed
2001    /// using the restore() function.
2002    ///
2003    /// \warning Edge and node deletions cannot be restored. This
2004    /// events invalidate the snapshot.
2005    class Snapshot {
2006    protected:
2007
2008      typedef Parent::NodeNotifier NodeNotifier;
2009
2010      class NodeObserverProxy : public NodeNotifier::ObserverBase {
2011      public:
2012
2013        NodeObserverProxy(Snapshot& _snapshot)
2014          : snapshot(_snapshot) {}
2015
2016        using NodeNotifier::ObserverBase::attach;
2017        using NodeNotifier::ObserverBase::detach;
2018        using NodeNotifier::ObserverBase::attached;
2019       
2020      protected:
2021       
2022        virtual void add(const Node& node) {
2023          snapshot.addNode(node);
2024        }
2025        virtual void add(const std::vector<Node>& nodes) {
2026          for (int i = nodes.size() - 1; i >= 0; ++i) {
2027            snapshot.addNode(nodes[i]);
2028          }
2029        }
2030        virtual void erase(const Node& node) {
2031          snapshot.eraseNode(node);
2032        }
2033        virtual void erase(const std::vector<Node>& nodes) {
2034          for (int i = 0; i < (int)nodes.size(); ++i) {
2035            snapshot.eraseNode(nodes[i]);
2036          }
2037        }
2038        virtual void build() {
2039          NodeNotifier* notifier = getNotifier();
2040          Node node;
2041          std::vector<Node> nodes;
2042          for (notifier->first(node); node != INVALID; notifier->next(node)) {
2043            nodes.push_back(node);
2044          }
2045          for (int i = nodes.size() - 1; i >= 0; --i) {
2046            snapshot.addNode(nodes[i]);
2047          }
2048        }
2049        virtual void clear() {
2050          NodeNotifier* notifier = getNotifier();
2051          Node node;
2052          for (notifier->first(node); node != INVALID; notifier->next(node)) {
2053            snapshot.eraseNode(node);
2054          }
2055        }
2056
2057        Snapshot& snapshot;
2058      };
2059
2060      class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
2061      public:
2062
2063        UEdgeObserverProxy(Snapshot& _snapshot)
2064          : snapshot(_snapshot) {}
2065
2066        using UEdgeNotifier::ObserverBase::attach;
2067        using UEdgeNotifier::ObserverBase::detach;
2068        using UEdgeNotifier::ObserverBase::attached;
2069       
2070      protected:
2071
2072        virtual void add(const UEdge& edge) {
2073          snapshot.addUEdge(edge);
2074        }
2075        virtual void add(const std::vector<UEdge>& edges) {
2076          for (int i = edges.size() - 1; i >= 0; ++i) {
2077            snapshot.addUEdge(edges[i]);
2078          }
2079        }
2080        virtual void erase(const UEdge& edge) {
2081          snapshot.eraseUEdge(edge);
2082        }
2083        virtual void erase(const std::vector<UEdge>& edges) {
2084          for (int i = 0; i < (int)edges.size(); ++i) {
2085            snapshot.eraseUEdge(edges[i]);
2086          }
2087        }
2088        virtual void build() {
2089          UEdgeNotifier* notifier = getNotifier();
2090          UEdge edge;
2091          std::vector<UEdge> edges;
2092          for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
2093            edges.push_back(edge);
2094          }
2095          for (int i = edges.size() - 1; i >= 0; --i) {
2096            snapshot.addUEdge(edges[i]);
2097          }
2098        }
2099        virtual void clear() {
2100          UEdgeNotifier* notifier = getNotifier();
2101          UEdge edge;
2102          for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
2103            snapshot.eraseUEdge(edge);
2104          }
2105        }
2106
2107        Snapshot& snapshot;
2108      };
2109     
2110      ListBpUGraph *graph;
2111
2112      NodeObserverProxy node_observer_proxy;
2113      UEdgeObserverProxy edge_observer_proxy;
2114
2115      std::list<Node> added_nodes;
2116      std::list<UEdge> added_edges;
2117
2118
2119      void addNode(const Node& node) {
2120        added_nodes.push_front(node);       
2121      }
2122      void eraseNode(const Node& node) {
2123        std::list<Node>::iterator it =
2124          std::find(added_nodes.begin(), added_nodes.end(), node);
2125        if (it == added_nodes.end()) {
2126          clear();
2127          edge_observer_proxy.detach();
2128          throw NodeNotifier::ImmediateDetach();
2129        } else {
2130          added_nodes.erase(it);
2131        }
2132      }
2133
2134      void addUEdge(const UEdge& edge) {
2135        added_edges.push_front(edge);       
2136      }
2137      void eraseUEdge(const UEdge& edge) {
2138        std::list<UEdge>::iterator it =
2139          std::find(added_edges.begin(), added_edges.end(), edge);
2140        if (it == added_edges.end()) {
2141          clear();
2142          node_observer_proxy.detach();
2143          throw UEdgeNotifier::ImmediateDetach();
2144        } else {
2145          added_edges.erase(it);
2146        }       
2147      }
2148
2149      void attach(ListBpUGraph &_graph) {
2150        graph = &_graph;
2151        node_observer_proxy.attach(graph->getNotifier(Node()));
2152        edge_observer_proxy.attach(graph->getNotifier(UEdge()));
2153      }
2154           
2155      void detach() {
2156        node_observer_proxy.detach();
2157        edge_observer_proxy.detach();
2158      }
2159
2160      bool attached() const {
2161        return node_observer_proxy.attached();
2162      }
2163
2164      void clear() {
2165        added_nodes.clear();
2166        added_edges.clear();       
2167      }
2168
2169    public:
2170
2171      /// \brief Default constructor.
2172      ///
2173      /// Default constructor.
2174      /// To actually make a snapshot you must call save().
2175      Snapshot()
2176        : graph(0), node_observer_proxy(*this),
2177          edge_observer_proxy(*this) {}
2178     
2179      /// \brief Constructor that immediately makes a snapshot.
2180      ///     
2181      /// This constructor immediately makes a snapshot of the graph.
2182      /// \param _graph The graph we make a snapshot of.
2183      Snapshot(ListBpUGraph &_graph)
2184        : node_observer_proxy(*this),
2185          edge_observer_proxy(*this) {
2186        attach(_graph);
2187      }
2188     
2189      /// \brief Make a snapshot.
2190      ///
2191      /// Make a snapshot of the graph.
2192      ///
2193      /// This function can be called more than once. In case of a repeated
2194      /// call, the previous snapshot gets lost.
2195      /// \param _graph The graph we make the snapshot of.
2196      void save(ListBpUGraph &_graph) {
2197        if (attached()) {
2198          detach();
2199          clear();
2200        }
2201        attach(_graph);
2202      }
2203     
2204      /// \brief Undo the changes until the last snapshot.
2205      //
2206      /// Undo the changes until the last snapshot created by save().
2207      void restore() {
2208        detach();
2209        for(std::list<UEdge>::iterator it = added_edges.begin();
2210            it != added_edges.end(); ++it) {
2211          graph->erase(*it);
2212        }
2213        for(std::list<Node>::iterator it = added_nodes.begin();
2214            it != added_nodes.end(); ++it) {
2215          graph->erase(*it);
2216        }
2217        clear();
2218      }
2219
2220      /// \brief Gives back true when the snapshot is valid.
2221      ///
2222      /// Gives back true when the snapshot is valid.
2223      bool valid() const {
2224        return attached();
2225      }
2226    };
2227  };
2228
2229 
2230  /// @} 
2231} //namespace lemon
2232 
2233
2234#endif
Note: See TracBrowser for help on using the repository browser.