COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/list_graph.h @ 2368:6b2e8b734ae7

Last change on this file since 2368:6b2e8b734ae7 was 2343:21587bc5922b, checked in by Balazs Dezso, 17 years ago

G++-3.3 conform solution

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