COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/list_graph.h @ 2338:359f0b71919b

Last change on this file since 2338:359f0b71919b was 2338:359f0b71919b, checked in by Balazs Dezso, 13 years ago

Changing implementation of undirected graphs
slightly faster, 10% speed-up

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