COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/list_graph.h @ 2334:c1e936e6a46b

Last change on this file since 2334:c1e936e6a46b was 2302:d3c664c975ee, checked in by Alpar Juttner, 17 years ago

Test the automatic compilation checker 1/2: fix the repo again

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