COIN-OR::LEMON - Graph Library

source: lemon/lemon/list_graph.h @ 782:853fcddcf282

Last change on this file since 782:853fcddcf282 was 782:853fcddcf282, checked in by Peter Kovacs <kpeter@…>, 15 years ago

Doc improvements, fixes and unifications for graphs (#311)

File size: 42.8 KB
RevLine 
[209]1/* -*- mode: C++; indent-tabs-mode: nil; -*-
[39]2 *
[209]3 * This file is a part of LEMON, a generic C++ optimization library.
[39]4 *
[463]5 * Copyright (C) 2003-2009
[39]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
[57]19#ifndef LEMON_LIST_GRAPH_H
20#define LEMON_LIST_GRAPH_H
21
22///\ingroup graphs
23///\file
[782]24///\brief ListDigraph and ListGraph classes.
[57]25
[220]26#include <lemon/core.h>
27#include <lemon/error.h>
[57]28#include <lemon/bits/graph_extender.h>
29
30#include <vector>
31#include <list>
32
33namespace lemon {
34
35  class ListDigraphBase {
36
37  protected:
38    struct NodeT {
39      int first_in, first_out;
40      int prev, next;
41    };
[209]42
[57]43    struct ArcT {
44      int target, source;
45      int prev_in, prev_out;
46      int next_in, next_out;
47    };
48
49    std::vector<NodeT> nodes;
50
51    int first_node;
52
53    int first_free_node;
54
55    std::vector<ArcT> arcs;
56
57    int first_free_arc;
[209]58
[57]59  public:
[209]60
[57]61    typedef ListDigraphBase Digraph;
[209]62
[57]63    class Node {
64      friend class ListDigraphBase;
65    protected:
66
67      int id;
68      explicit Node(int pid) { id = pid;}
69
70    public:
71      Node() {}
72      Node (Invalid) { id = -1; }
73      bool operator==(const Node& node) const {return id == node.id;}
74      bool operator!=(const Node& node) const {return id != node.id;}
75      bool operator<(const Node& node) const {return id < node.id;}
76    };
77
78    class Arc {
79      friend class ListDigraphBase;
80    protected:
81
82      int id;
83      explicit Arc(int pid) { id = pid;}
84
85    public:
86      Arc() {}
87      Arc (Invalid) { id = -1; }
88      bool operator==(const Arc& arc) const {return id == arc.id;}
89      bool operator!=(const Arc& arc) const {return id != arc.id;}
90      bool operator<(const Arc& arc) const {return id < arc.id;}
91    };
92
93
94
95    ListDigraphBase()
96      : nodes(), first_node(-1),
[209]97        first_free_node(-1), arcs(), first_free_arc(-1) {}
[57]98
[209]99
100    int maxNodeId() const { return nodes.size()-1; }
[57]101    int maxArcId() const { return arcs.size()-1; }
102
103    Node source(Arc e) const { return Node(arcs[e.id].source); }
104    Node target(Arc e) const { return Node(arcs[e.id].target); }
105
106
[209]107    void first(Node& node) const {
[57]108      node.id = first_node;
109    }
110
111    void next(Node& node) const {
112      node.id = nodes[node.id].next;
113    }
114
115
[209]116    void first(Arc& arc) const {
[57]117      int n;
[209]118      for(n = first_node;
119          n!=-1 && nodes[n].first_in == -1;
120          n = nodes[n].next) {}
[73]121      arc.id = (n == -1) ? -1 : nodes[n].first_in;
[57]122    }
123
124    void next(Arc& arc) const {
125      if (arcs[arc.id].next_in != -1) {
[209]126        arc.id = arcs[arc.id].next_in;
[57]127      } else {
[209]128        int n;
129        for(n = nodes[arcs[arc.id].target].next;
130            n!=-1 && nodes[n].first_in == -1;
131            n = nodes[n].next) {}
132        arc.id = (n == -1) ? -1 : nodes[n].first_in;
133      }
[57]134    }
135
136    void firstOut(Arc &e, const Node& v) const {
137      e.id = nodes[v.id].first_out;
138    }
139    void nextOut(Arc &e) const {
140      e.id=arcs[e.id].next_out;
141    }
142
143    void firstIn(Arc &e, const Node& v) const {
144      e.id = nodes[v.id].first_in;
145    }
146    void nextIn(Arc &e) const {
147      e.id=arcs[e.id].next_in;
148    }
149
[209]150
[57]151    static int id(Node v) { return v.id; }
152    static int id(Arc e) { return e.id; }
153
154    static Node nodeFromId(int id) { return Node(id);}
155    static Arc arcFromId(int id) { return Arc(id);}
156
[209]157    bool valid(Node n) const {
158      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159        nodes[n.id].prev != -2;
[149]160    }
161
[209]162    bool valid(Arc a) const {
163      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164        arcs[a.id].prev_in != -2;
[149]165    }
166
[209]167    Node addNode() {
[57]168      int n;
[209]169
[57]170      if(first_free_node==-1) {
[209]171        n = nodes.size();
172        nodes.push_back(NodeT());
[57]173      } else {
[209]174        n = first_free_node;
175        first_free_node = nodes[n].next;
[57]176      }
[209]177
[57]178      nodes[n].next = first_node;
179      if(first_node != -1) nodes[first_node].prev = n;
180      first_node = n;
181      nodes[n].prev = -1;
[209]182
[57]183      nodes[n].first_in = nodes[n].first_out = -1;
[209]184
[57]185      return Node(n);
186    }
[209]187
[57]188    Arc addArc(Node u, Node v) {
[209]189      int n;
[57]190
191      if (first_free_arc == -1) {
[209]192        n = arcs.size();
193        arcs.push_back(ArcT());
[57]194      } else {
[209]195        n = first_free_arc;
196        first_free_arc = arcs[n].next_in;
[57]197      }
[209]198
199      arcs[n].source = u.id;
[57]200      arcs[n].target = v.id;
201
202      arcs[n].next_out = nodes[u.id].first_out;
203      if(nodes[u.id].first_out != -1) {
[209]204        arcs[nodes[u.id].first_out].prev_out = n;
[57]205      }
[209]206
[57]207      arcs[n].next_in = nodes[v.id].first_in;
208      if(nodes[v.id].first_in != -1) {
[209]209        arcs[nodes[v.id].first_in].prev_in = n;
[57]210      }
[209]211
[57]212      arcs[n].prev_in = arcs[n].prev_out = -1;
[209]213
[57]214      nodes[u.id].first_out = nodes[v.id].first_in = n;
215
216      return Arc(n);
217    }
[209]218
[57]219    void erase(const Node& node) {
220      int n = node.id;
[209]221
[57]222      if(nodes[n].next != -1) {
[209]223        nodes[nodes[n].next].prev = nodes[n].prev;
[57]224      }
[209]225
[57]226      if(nodes[n].prev != -1) {
[209]227        nodes[nodes[n].prev].next = nodes[n].next;
[57]228      } else {
[209]229        first_node = nodes[n].next;
[57]230      }
[209]231
[57]232      nodes[n].next = first_free_node;
233      first_free_node = n;
[149]234      nodes[n].prev = -2;
[57]235
236    }
[209]237
[57]238    void erase(const Arc& arc) {
239      int n = arc.id;
[209]240
[57]241      if(arcs[n].next_in!=-1) {
[209]242        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
[57]243      }
244
245      if(arcs[n].prev_in!=-1) {
[209]246        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
[57]247      } else {
[209]248        nodes[arcs[n].target].first_in = arcs[n].next_in;
[57]249      }
250
[209]251
[57]252      if(arcs[n].next_out!=-1) {
[209]253        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254      }
[57]255
256      if(arcs[n].prev_out!=-1) {
[209]257        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
[57]258      } else {
[209]259        nodes[arcs[n].source].first_out = arcs[n].next_out;
[57]260      }
[209]261
[57]262      arcs[n].next_in = first_free_arc;
[149]263      first_free_arc = n;
264      arcs[n].prev_in = -2;
[57]265    }
266
267    void clear() {
268      arcs.clear();
269      nodes.clear();
270      first_node = first_free_node = first_free_arc = -1;
271    }
272
273  protected:
[209]274    void changeTarget(Arc e, Node n)
[57]275    {
276      if(arcs[e.id].next_in != -1)
[209]277        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
[57]278      if(arcs[e.id].prev_in != -1)
[209]279        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
[57]280      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
281      if (nodes[n.id].first_in != -1) {
[209]282        arcs[nodes[n.id].first_in].prev_in = e.id;
[57]283      }
284      arcs[e.id].target = n.id;
285      arcs[e.id].prev_in = -1;
286      arcs[e.id].next_in = nodes[n.id].first_in;
287      nodes[n.id].first_in = e.id;
288    }
[209]289    void changeSource(Arc e, Node n)
[57]290    {
291      if(arcs[e.id].next_out != -1)
[209]292        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
[57]293      if(arcs[e.id].prev_out != -1)
[209]294        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
[57]295      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
296      if (nodes[n.id].first_out != -1) {
[209]297        arcs[nodes[n.id].first_out].prev_out = e.id;
[57]298      }
299      arcs[e.id].source = n.id;
300      arcs[e.id].prev_out = -1;
301      arcs[e.id].next_out = nodes[n.id].first_out;
302      nodes[n.id].first_out = e.id;
303    }
304
305  };
306
307  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308
[73]309  /// \addtogroup graphs
[57]310  /// @{
311
[209]312  ///A general directed graph structure.
[57]313
[782]314  ///\ref ListDigraph is a versatile and fast directed graph
315  ///implementation based on linked lists that are stored in
[209]316  ///\c std::vector structures.
[57]317  ///
[782]318  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
319  ///and it also provides several useful additional functionalities.
320  ///Most of its member functions and nested classes are documented
[73]321  ///only in the concept class.
[57]322  ///
[73]323  ///\sa concepts::Digraph
[782]324  ///\sa ListGraph
[57]325  class ListDigraph : public ExtendedListDigraphBase {
[664]326    typedef ExtendedListDigraphBase Parent;
327
[57]328  private:
[782]329    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
[57]330    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
[782]331    /// \brief Assignment of a digraph to another one is \e not allowed.
332    /// Use DigraphCopy instead.
[57]333    void operator=(const ListDigraph &) {}
334  public:
335
336    /// Constructor
[209]337
[57]338    /// Constructor.
339    ///
340    ListDigraph() {}
341
342    ///Add a new node to the digraph.
[209]343
[782]344    ///This function adds a new node to the digraph.
[606]345    ///\return The new node.
[57]346    Node addNode() { return Parent::addNode(); }
347
348    ///Add a new arc to the digraph.
[209]349
[782]350    ///This function adds a new arc to the digraph with source node \c s
[57]351    ///and target node \c t.
[606]352    ///\return The new arc.
[782]353    Arc addArc(Node s, Node t) {
[209]354      return Parent::addArc(s, t);
[57]355    }
356
[234]357    ///\brief Erase a node from the digraph.
358    ///
[782]359    ///This function erases the given node from the digraph.
360    void erase(Node n) { Parent::erase(n); }
[234]361
362    ///\brief Erase an arc from the digraph.
363    ///
[782]364    ///This function erases the given arc from the digraph.
365    void erase(Arc a) { Parent::erase(a); }
[234]366
[149]367    /// Node validity check
368
[782]369    /// This function gives back \c true if the given node is valid,
370    /// i.e. it is a real node of the digraph.
[149]371    ///
[782]372    /// \warning A removed node could become valid again if new nodes are
373    /// added to the digraph.
[149]374    bool valid(Node n) const { return Parent::valid(n); }
375
376    /// Arc validity check
377
[782]378    /// This function gives back \c true if the given arc is valid,
379    /// i.e. it is a real arc of the digraph.
[149]380    ///
[782]381    /// \warning A removed arc could become valid again if new arcs are
382    /// added to the digraph.
[149]383    bool valid(Arc a) const { return Parent::valid(a); }
384
[782]385    /// Change the target node of an arc
[57]386
[782]387    /// This function changes the target node of the given arc \c a to \c n.
[57]388    ///
[782]389    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
390    ///arc remain valid, however \c InArcIt iterators are invalidated.
[73]391    ///
[57]392    ///\warning This functionality cannot be used together with the Snapshot
393    ///feature.
[235]394    void changeTarget(Arc a, Node n) {
395      Parent::changeTarget(a,n);
[57]396    }
[782]397    /// Change the source node of an arc
[57]398
[782]399    /// This function changes the source node of the given arc \c a to \c n.
[57]400    ///
[782]401    ///\note \c InArcIt iterators referencing the changed arc remain
402    ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
[73]403    ///
[57]404    ///\warning This functionality cannot be used together with the Snapshot
405    ///feature.
[235]406    void changeSource(Arc a, Node n) {
407      Parent::changeSource(a,n);
[57]408    }
409
[782]410    /// Reverse the direction of an arc.
[57]411
[782]412    /// This function reverses the direction of the given arc.
413    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
414    ///the changed arc are invalidated.
[73]415    ///
[57]416    ///\warning This functionality cannot be used together with the Snapshot
417    ///feature.
[782]418    void reverseArc(Arc a) {
419      Node t=target(a);
420      changeTarget(a,source(a));
421      changeSource(a,t);
[57]422    }
423
424    ///Contract two nodes.
425
[782]426    ///This function contracts the given two nodes.
427    ///Node \c v is removed, but instead of deleting its
428    ///incident arcs, they are joined to node \c u.
429    ///If the last parameter \c r is \c true (this is the default value),
430    ///then the newly created loops are removed.
[57]431    ///
[782]432    ///\note The moved arcs are joined to node \c u using changeSource()
433    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
434    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
435    ///iterators are invalidated for the incomming arcs of \c v.
436    ///Moreover all iterators referencing node \c v or the removed
437    ///loops are also invalidated. Other iterators remain valid.
[73]438    ///
[57]439    ///\warning This functionality cannot be used together with the Snapshot
440    ///feature.
[782]441    void contract(Node u, Node v, bool r = true)
[57]442    {
[782]443      for(OutArcIt e(*this,v);e!=INVALID;) {
[209]444        OutArcIt f=e;
445        ++f;
[782]446        if(r && target(e)==u) erase(e);
447        else changeSource(e,u);
[209]448        e=f;
[57]449      }
[782]450      for(InArcIt e(*this,v);e!=INVALID;) {
[209]451        InArcIt f=e;
452        ++f;
[782]453        if(r && source(e)==u) erase(e);
454        else changeTarget(e,u);
[209]455        e=f;
[57]456      }
[782]457      erase(v);
[57]458    }
459
460    ///Split a node.
461
[782]462    ///This function splits the given node. First, a new node is added
463    ///to the digraph, then the source of each outgoing arc of node \c n
464    ///is moved to this new node.
465    ///If the second parameter \c connect is \c true (this is the default
466    ///value), then a new arc from node \c n to the newly created node
467    ///is also added.
[57]468    ///\return The newly created node.
469    ///
[782]470    ///\note \c ArcIt and \c OutArcIt iterators referencing the outgoing
471    ///arcs of node \c n are invalidated. Other iterators remain valid.
[57]472    ///
[782]473    ///\warning This functionality cannot be used together with the
[73]474    ///Snapshot feature.
[57]475    Node split(Node n, bool connect = true) {
476      Node b = addNode();
477      for(OutArcIt e(*this,n);e!=INVALID;) {
[212]478        OutArcIt f=e;
[209]479        ++f;
480        changeSource(e,b);
481        e=f;
[57]482      }
483      if (connect) addArc(n,b);
484      return b;
485    }
[209]486
[57]487    ///Split an arc.
488
[782]489    ///This function splits the given arc. First, a new node \c v is
490    ///added to the digraph, then the target node of the original arc
491    ///is set to \c v. Finally, an arc from \c v to the original target
492    ///is added.
493    ///\return The newly created node.
[73]494    ///
[782]495    ///\note \c InArcIt iterators referencing the original arc are
496    ///invalidated. Other iterators remain valid.
[73]497    ///
498    ///\warning This functionality cannot be used together with the
499    ///Snapshot feature.
[782]500    Node split(Arc a) {
501      Node v = addNode();
502      addArc(v,target(a));
503      changeTarget(a,v);
504      return v;
[57]505    }
[209]506
[782]507    ///Clear the digraph.
508
509    ///This function erases all nodes and arcs from the digraph.
510    ///
511    void clear() {
512      Parent::clear();
513    }
514
515    /// Reserve memory for nodes.
516
517    /// Using this function, it is possible to avoid superfluous memory
518    /// allocation: if you know that the digraph you want to build will
519    /// be large (e.g. it will contain millions of nodes and/or arcs),
520    /// then it is worth reserving space for this amount before starting
521    /// to build the digraph.
522    /// \sa reserveArc()
523    void reserveNode(int n) { nodes.reserve(n); };
524
525    /// Reserve memory for arcs.
526
527    /// Using this function, it is possible to avoid superfluous memory
528    /// allocation: if you know that the digraph you want to build will
529    /// be large (e.g. it will contain millions of nodes and/or arcs),
530    /// then it is worth reserving space for this amount before starting
531    /// to build the digraph.
532    /// \sa reserveNode()
533    void reserveArc(int m) { arcs.reserve(m); };
534
[57]535    /// \brief Class to make a snapshot of the digraph and restore
[73]536    /// it later.
[57]537    ///
[73]538    /// Class to make a snapshot of the digraph and restore it later.
[57]539    ///
540    /// The newly added nodes and arcs can be removed using the
541    /// restore() function.
542    ///
[782]543    /// \note After a state is restored, you cannot restore a later state,
544    /// i.e. you cannot add the removed nodes and arcs again using
545    /// another Snapshot instance.
546    ///
547    /// \warning Node and arc deletions and other modifications (e.g.
548    /// reversing, contracting, splitting arcs or nodes) cannot be
[209]549    /// restored. These events invalidate the snapshot.
[782]550    /// However the arcs and nodes that were added to the digraph after
551    /// making the current snapshot can be removed without invalidating it.
[57]552    class Snapshot {
553    protected:
554
555      typedef Parent::NodeNotifier NodeNotifier;
556
557      class NodeObserverProxy : public NodeNotifier::ObserverBase {
558      public:
559
560        NodeObserverProxy(Snapshot& _snapshot)
561          : snapshot(_snapshot) {}
562
563        using NodeNotifier::ObserverBase::attach;
564        using NodeNotifier::ObserverBase::detach;
565        using NodeNotifier::ObserverBase::attached;
[209]566
[57]567      protected:
[209]568
[57]569        virtual void add(const Node& node) {
570          snapshot.addNode(node);
571        }
572        virtual void add(const std::vector<Node>& nodes) {
573          for (int i = nodes.size() - 1; i >= 0; ++i) {
574            snapshot.addNode(nodes[i]);
575          }
576        }
577        virtual void erase(const Node& node) {
578          snapshot.eraseNode(node);
579        }
580        virtual void erase(const std::vector<Node>& nodes) {
581          for (int i = 0; i < int(nodes.size()); ++i) {
582            snapshot.eraseNode(nodes[i]);
583          }
584        }
585        virtual void build() {
586          Node node;
587          std::vector<Node> nodes;
[209]588          for (notifier()->first(node); node != INVALID;
[57]589               notifier()->next(node)) {
590            nodes.push_back(node);
591          }
592          for (int i = nodes.size() - 1; i >= 0; --i) {
593            snapshot.addNode(nodes[i]);
594          }
595        }
596        virtual void clear() {
597          Node node;
[209]598          for (notifier()->first(node); node != INVALID;
[57]599               notifier()->next(node)) {
600            snapshot.eraseNode(node);
601          }
602        }
603
604        Snapshot& snapshot;
605      };
606
607      class ArcObserverProxy : public ArcNotifier::ObserverBase {
608      public:
609
610        ArcObserverProxy(Snapshot& _snapshot)
611          : snapshot(_snapshot) {}
612
613        using ArcNotifier::ObserverBase::attach;
614        using ArcNotifier::ObserverBase::detach;
615        using ArcNotifier::ObserverBase::attached;
[209]616
[57]617      protected:
618
619        virtual void add(const Arc& arc) {
620          snapshot.addArc(arc);
621        }
622        virtual void add(const std::vector<Arc>& arcs) {
623          for (int i = arcs.size() - 1; i >= 0; ++i) {
624            snapshot.addArc(arcs[i]);
625          }
626        }
627        virtual void erase(const Arc& arc) {
628          snapshot.eraseArc(arc);
629        }
630        virtual void erase(const std::vector<Arc>& arcs) {
631          for (int i = 0; i < int(arcs.size()); ++i) {
632            snapshot.eraseArc(arcs[i]);
633          }
634        }
635        virtual void build() {
636          Arc arc;
637          std::vector<Arc> arcs;
[209]638          for (notifier()->first(arc); arc != INVALID;
[57]639               notifier()->next(arc)) {
640            arcs.push_back(arc);
641          }
642          for (int i = arcs.size() - 1; i >= 0; --i) {
643            snapshot.addArc(arcs[i]);
644          }
645        }
646        virtual void clear() {
647          Arc arc;
[209]648          for (notifier()->first(arc); arc != INVALID;
[57]649               notifier()->next(arc)) {
650            snapshot.eraseArc(arc);
651          }
652        }
653
654        Snapshot& snapshot;
655      };
[209]656
[57]657      ListDigraph *digraph;
658
659      NodeObserverProxy node_observer_proxy;
660      ArcObserverProxy arc_observer_proxy;
661
662      std::list<Node> added_nodes;
663      std::list<Arc> added_arcs;
664
665
666      void addNode(const Node& node) {
[209]667        added_nodes.push_front(node);
[57]668      }
669      void eraseNode(const Node& node) {
[209]670        std::list<Node>::iterator it =
[57]671          std::find(added_nodes.begin(), added_nodes.end(), node);
672        if (it == added_nodes.end()) {
673          clear();
674          arc_observer_proxy.detach();
675          throw NodeNotifier::ImmediateDetach();
676        } else {
677          added_nodes.erase(it);
678        }
679      }
680
681      void addArc(const Arc& arc) {
[209]682        added_arcs.push_front(arc);
[57]683      }
684      void eraseArc(const Arc& arc) {
[209]685        std::list<Arc>::iterator it =
[57]686          std::find(added_arcs.begin(), added_arcs.end(), arc);
687        if (it == added_arcs.end()) {
688          clear();
[209]689          node_observer_proxy.detach();
[57]690          throw ArcNotifier::ImmediateDetach();
691        } else {
692          added_arcs.erase(it);
[209]693        }
[57]694      }
695
696      void attach(ListDigraph &_digraph) {
[209]697        digraph = &_digraph;
698        node_observer_proxy.attach(digraph->notifier(Node()));
[57]699        arc_observer_proxy.attach(digraph->notifier(Arc()));
700      }
[209]701
[57]702      void detach() {
[209]703        node_observer_proxy.detach();
704        arc_observer_proxy.detach();
[57]705      }
706
707      bool attached() const {
708        return node_observer_proxy.attached();
709      }
710
711      void clear() {
712        added_nodes.clear();
[209]713        added_arcs.clear();
[57]714      }
715
716    public:
717
718      /// \brief Default constructor.
719      ///
720      /// Default constructor.
[782]721      /// You have to call save() to actually make a snapshot.
[209]722      Snapshot()
723        : digraph(0), node_observer_proxy(*this),
[57]724          arc_observer_proxy(*this) {}
[209]725
[57]726      /// \brief Constructor that immediately makes a snapshot.
[209]727      ///
[782]728      /// This constructor immediately makes a snapshot of the given digraph.
729      Snapshot(ListDigraph &gr)
[209]730        : node_observer_proxy(*this),
[57]731          arc_observer_proxy(*this) {
[782]732        attach(gr);
[57]733      }
[209]734
[57]735      /// \brief Make a snapshot.
736      ///
[782]737      /// This function makes a snapshot of the given digraph.
738      /// It can be called more than once. In case of a repeated
[57]739      /// call, the previous snapshot gets lost.
[782]740      void save(ListDigraph &gr) {
[57]741        if (attached()) {
742          detach();
743          clear();
744        }
[782]745        attach(gr);
[57]746      }
[209]747
[57]748      /// \brief Undo the changes until the last snapshot.
[782]749      ///
750      /// This function undos the changes until the last snapshot
751      /// created by save() or Snapshot(ListDigraph&).
[57]752      void restore() {
[209]753        detach();
754        for(std::list<Arc>::iterator it = added_arcs.begin();
[57]755            it != added_arcs.end(); ++it) {
[209]756          digraph->erase(*it);
757        }
758        for(std::list<Node>::iterator it = added_nodes.begin();
[57]759            it != added_nodes.end(); ++it) {
[209]760          digraph->erase(*it);
761        }
[57]762        clear();
763      }
764
[782]765      /// \brief Returns \c true if the snapshot is valid.
[57]766      ///
[782]767      /// This function returns \c true if the snapshot is valid.
[57]768      bool valid() const {
769        return attached();
770      }
771    };
[209]772
[57]773  };
774
775  ///@}
776
777  class ListGraphBase {
778
779  protected:
780
781    struct NodeT {
782      int first_out;
783      int prev, next;
784    };
[209]785
[57]786    struct ArcT {
787      int target;
788      int prev_out, next_out;
789    };
790
791    std::vector<NodeT> nodes;
792
793    int first_node;
794
795    int first_free_node;
796
797    std::vector<ArcT> arcs;
798
799    int first_free_arc;
[209]800
[57]801  public:
[209]802
[664]803    typedef ListGraphBase Graph;
[57]804
805    class Node {
806      friend class ListGraphBase;
807    protected:
808
809      int id;
810      explicit Node(int pid) { id = pid;}
811
812    public:
813      Node() {}
814      Node (Invalid) { id = -1; }
815      bool operator==(const Node& node) const {return id == node.id;}
816      bool operator!=(const Node& node) const {return id != node.id;}
817      bool operator<(const Node& node) const {return id < node.id;}
818    };
819
820    class Edge {
821      friend class ListGraphBase;
822    protected:
823
824      int id;
825      explicit Edge(int pid) { id = pid;}
826
827    public:
828      Edge() {}
829      Edge (Invalid) { id = -1; }
[73]830      bool operator==(const Edge& edge) const {return id == edge.id;}
831      bool operator!=(const Edge& edge) const {return id != edge.id;}
832      bool operator<(const Edge& edge) const {return id < edge.id;}
[57]833    };
834
835    class Arc {
836      friend class ListGraphBase;
837    protected:
838
839      int id;
840      explicit Arc(int pid) { id = pid;}
841
842    public:
[341]843      operator Edge() const {
844        return id != -1 ? edgeFromId(id / 2) : INVALID;
[238]845      }
[57]846
847      Arc() {}
848      Arc (Invalid) { id = -1; }
849      bool operator==(const Arc& arc) const {return id == arc.id;}
850      bool operator!=(const Arc& arc) const {return id != arc.id;}
851      bool operator<(const Arc& arc) const {return id < arc.id;}
852    };
853
854    ListGraphBase()
855      : nodes(), first_node(-1),
[209]856        first_free_node(-1), arcs(), first_free_arc(-1) {}
[57]857
[209]858
859    int maxNodeId() const { return nodes.size()-1; }
[57]860    int maxEdgeId() const { return arcs.size() / 2 - 1; }
861    int maxArcId() const { return arcs.size()-1; }
862
863    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
864    Node target(Arc e) const { return Node(arcs[e.id].target); }
865
866    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
867    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
868
869    static bool direction(Arc e) {
870      return (e.id & 1) == 1;
871    }
872
873    static Arc direct(Edge e, bool d) {
874      return Arc(e.id * 2 + (d ? 1 : 0));
875    }
876
[209]877    void first(Node& node) const {
[57]878      node.id = first_node;
879    }
880
881    void next(Node& node) const {
882      node.id = nodes[node.id].next;
883    }
884
[209]885    void first(Arc& e) const {
[57]886      int n = first_node;
887      while (n != -1 && nodes[n].first_out == -1) {
888        n = nodes[n].next;
889      }
890      e.id = (n == -1) ? -1 : nodes[n].first_out;
891    }
892
893    void next(Arc& e) const {
894      if (arcs[e.id].next_out != -1) {
[209]895        e.id = arcs[e.id].next_out;
[57]896      } else {
[209]897        int n = nodes[arcs[e.id ^ 1].target].next;
[57]898        while(n != -1 && nodes[n].first_out == -1) {
899          n = nodes[n].next;
900        }
[209]901        e.id = (n == -1) ? -1 : nodes[n].first_out;
902      }
[57]903    }
904
[209]905    void first(Edge& e) const {
[57]906      int n = first_node;
907      while (n != -1) {
908        e.id = nodes[n].first_out;
909        while ((e.id & 1) != 1) {
910          e.id = arcs[e.id].next_out;
911        }
912        if (e.id != -1) {
913          e.id /= 2;
914          return;
[209]915        }
[57]916        n = nodes[n].next;
917      }
918      e.id = -1;
919    }
920
921    void next(Edge& e) const {
922      int n = arcs[e.id * 2].target;
923      e.id = arcs[(e.id * 2) | 1].next_out;
924      while ((e.id & 1) != 1) {
925        e.id = arcs[e.id].next_out;
926      }
927      if (e.id != -1) {
928        e.id /= 2;
929        return;
[209]930      }
[57]931      n = nodes[n].next;
932      while (n != -1) {
933        e.id = nodes[n].first_out;
934        while ((e.id & 1) != 1) {
935          e.id = arcs[e.id].next_out;
936        }
937        if (e.id != -1) {
938          e.id /= 2;
939          return;
[209]940        }
[57]941        n = nodes[n].next;
942      }
943      e.id = -1;
944    }
945
946    void firstOut(Arc &e, const Node& v) const {
947      e.id = nodes[v.id].first_out;
948    }
949    void nextOut(Arc &e) const {
950      e.id = arcs[e.id].next_out;
951    }
952
953    void firstIn(Arc &e, const Node& v) const {
954      e.id = ((nodes[v.id].first_out) ^ 1);
955      if (e.id == -2) e.id = -1;
956    }
957    void nextIn(Arc &e) const {
958      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
959      if (e.id == -2) e.id = -1;
960    }
961
962    void firstInc(Edge &e, bool& d, const Node& v) const {
[73]963      int a = nodes[v.id].first_out;
964      if (a != -1 ) {
965        e.id = a / 2;
966        d = ((a & 1) == 1);
[57]967      } else {
968        e.id = -1;
969        d = true;
970      }
971    }
972    void nextInc(Edge &e, bool& d) const {
[73]973      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
974      if (a != -1 ) {
975        e.id = a / 2;
976        d = ((a & 1) == 1);
[57]977      } else {
978        e.id = -1;
979        d = true;
980      }
981    }
[209]982
[57]983    static int id(Node v) { return v.id; }
984    static int id(Arc e) { return e.id; }
985    static int id(Edge e) { return e.id; }
986
987    static Node nodeFromId(int id) { return Node(id);}
988    static Arc arcFromId(int id) { return Arc(id);}
989    static Edge edgeFromId(int id) { return Edge(id);}
990
[209]991    bool valid(Node n) const {
992      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
993        nodes[n.id].prev != -2;
[149]994    }
995
[209]996    bool valid(Arc a) const {
997      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
998        arcs[a.id].prev_out != -2;
[149]999    }
1000
[209]1001    bool valid(Edge e) const {
1002      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1003        arcs[2 * e.id].prev_out != -2;
[149]1004    }
1005
[209]1006    Node addNode() {
[57]1007      int n;
[209]1008
[57]1009      if(first_free_node==-1) {
[209]1010        n = nodes.size();
1011        nodes.push_back(NodeT());
[57]1012      } else {
[209]1013        n = first_free_node;
1014        first_free_node = nodes[n].next;
[57]1015      }
[209]1016
[57]1017      nodes[n].next = first_node;
1018      if (first_node != -1) nodes[first_node].prev = n;
1019      first_node = n;
1020      nodes[n].prev = -1;
[209]1021
[57]1022      nodes[n].first_out = -1;
[209]1023
[57]1024      return Node(n);
1025    }
[209]1026
[57]1027    Edge addEdge(Node u, Node v) {
[209]1028      int n;
[57]1029
1030      if (first_free_arc == -1) {
[209]1031        n = arcs.size();
1032        arcs.push_back(ArcT());
1033        arcs.push_back(ArcT());
[57]1034      } else {
[209]1035        n = first_free_arc;
1036        first_free_arc = arcs[n].next_out;
[57]1037      }
[209]1038
[57]1039      arcs[n].target = u.id;
1040      arcs[n | 1].target = v.id;
1041
1042      arcs[n].next_out = nodes[v.id].first_out;
1043      if (nodes[v.id].first_out != -1) {
[209]1044        arcs[nodes[v.id].first_out].prev_out = n;
1045      }
[57]1046      arcs[n].prev_out = -1;
1047      nodes[v.id].first_out = n;
[209]1048
[57]1049      arcs[n | 1].next_out = nodes[u.id].first_out;
1050      if (nodes[u.id].first_out != -1) {
[209]1051        arcs[nodes[u.id].first_out].prev_out = (n | 1);
[57]1052      }
[209]1053      arcs[n | 1].prev_out = -1;
[57]1054      nodes[u.id].first_out = (n | 1);
1055
1056      return Edge(n / 2);
1057    }
[209]1058
[57]1059    void erase(const Node& node) {
1060      int n = node.id;
[209]1061
[57]1062      if(nodes[n].next != -1) {
[209]1063        nodes[nodes[n].next].prev = nodes[n].prev;
[57]1064      }
[209]1065
[57]1066      if(nodes[n].prev != -1) {
[209]1067        nodes[nodes[n].prev].next = nodes[n].next;
[57]1068      } else {
[209]1069        first_node = nodes[n].next;
[57]1070      }
[209]1071
[57]1072      nodes[n].next = first_free_node;
1073      first_free_node = n;
[149]1074      nodes[n].prev = -2;
[57]1075    }
[209]1076
[73]1077    void erase(const Edge& edge) {
1078      int n = edge.id * 2;
[209]1079
[57]1080      if (arcs[n].next_out != -1) {
[209]1081        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1082      }
[57]1083
1084      if (arcs[n].prev_out != -1) {
[209]1085        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
[57]1086      } else {
[209]1087        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
[57]1088      }
1089
1090      if (arcs[n | 1].next_out != -1) {
[209]1091        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1092      }
[57]1093
1094      if (arcs[n | 1].prev_out != -1) {
[209]1095        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
[57]1096      } else {
[209]1097        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
[57]1098      }
[209]1099
[57]1100      arcs[n].next_out = first_free_arc;
[209]1101      first_free_arc = n;
[149]1102      arcs[n].prev_out = -2;
1103      arcs[n | 1].prev_out = -2;
[57]1104
1105    }
1106
1107    void clear() {
1108      arcs.clear();
1109      nodes.clear();
1110      first_node = first_free_node = first_free_arc = -1;
1111    }
1112
1113  protected:
1114
[235]1115    void changeV(Edge e, Node n) {
[57]1116      if(arcs[2 * e.id].next_out != -1) {
[209]1117        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
[57]1118      }
1119      if(arcs[2 * e.id].prev_out != -1) {
[209]1120        arcs[arcs[2 * e.id].prev_out].next_out =
[57]1121          arcs[2 * e.id].next_out;
1122      } else {
[209]1123        nodes[arcs[(2 * e.id) | 1].target].first_out =
[57]1124          arcs[2 * e.id].next_out;
1125      }
1126
1127      if (nodes[n.id].first_out != -1) {
[209]1128        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
[57]1129      }
1130      arcs[(2 * e.id) | 1].target = n.id;
1131      arcs[2 * e.id].prev_out = -1;
1132      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1133      nodes[n.id].first_out = 2 * e.id;
1134    }
1135
[235]1136    void changeU(Edge e, Node n) {
[57]1137      if(arcs[(2 * e.id) | 1].next_out != -1) {
[209]1138        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
[57]1139          arcs[(2 * e.id) | 1].prev_out;
1140      }
1141      if(arcs[(2 * e.id) | 1].prev_out != -1) {
[209]1142        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
[57]1143          arcs[(2 * e.id) | 1].next_out;
1144      } else {
[209]1145        nodes[arcs[2 * e.id].target].first_out =
[57]1146          arcs[(2 * e.id) | 1].next_out;
1147      }
1148
1149      if (nodes[n.id].first_out != -1) {
[209]1150        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
[57]1151      }
1152      arcs[2 * e.id].target = n.id;
1153      arcs[(2 * e.id) | 1].prev_out = -1;
1154      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1155      nodes[n.id].first_out = ((2 * e.id) | 1);
1156    }
1157
1158  };
1159
1160  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1161
1162
[73]1163  /// \addtogroup graphs
[57]1164  /// @{
1165
[73]1166  ///A general undirected graph structure.
[57]1167
[782]1168  ///\ref ListGraph is a versatile and fast undirected graph
1169  ///implementation based on linked lists that are stored in
[209]1170  ///\c std::vector structures.
[57]1171  ///
[782]1172  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1173  ///and it also provides several useful additional functionalities.
1174  ///Most of its member functions and nested classes are documented
[73]1175  ///only in the concept class.
1176  ///
1177  ///\sa concepts::Graph
[782]1178  ///\sa ListDigraph
[57]1179  class ListGraph : public ExtendedListGraphBase {
[664]1180    typedef ExtendedListGraphBase Parent;
1181
[57]1182  private:
[782]1183    /// Graphs are \e not copy constructible. Use GraphCopy instead.
[57]1184    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
[782]1185    /// \brief Assignment of a graph to another one is \e not allowed.
1186    /// Use GraphCopy instead.
[57]1187    void operator=(const ListGraph &) {}
1188  public:
1189    /// Constructor
[209]1190
[57]1191    /// Constructor.
1192    ///
1193    ListGraph() {}
1194
[73]1195    typedef Parent::OutArcIt IncEdgeIt;
[57]1196
[73]1197    /// \brief Add a new node to the graph.
[57]1198    ///
[782]1199    /// This function adds a new node to the graph.
[606]1200    /// \return The new node.
[57]1201    Node addNode() { return Parent::addNode(); }
1202
[73]1203    /// \brief Add a new edge to the graph.
[57]1204    ///
[782]1205    /// This function adds a new edge to the graph between nodes
1206    /// \c u and \c v with inherent orientation from node \c u to
1207    /// node \c v.
[606]1208    /// \return The new edge.
[782]1209    Edge addEdge(Node u, Node v) {
1210      return Parent::addEdge(u, v);
[57]1211    }
[234]1212
[782]1213    ///\brief Erase a node from the graph.
[234]1214    ///
[782]1215    /// This function erases the given node from the graph.
1216    void erase(Node n) { Parent::erase(n); }
1217
1218    ///\brief Erase an edge from the graph.
[234]1219    ///
[782]1220    /// This function erases the given edge from the graph.
1221    void erase(Edge e) { Parent::erase(e); }
[149]1222    /// Node validity check
1223
[782]1224    /// This function gives back \c true if the given node is valid,
1225    /// i.e. it is a real node of the graph.
[149]1226    ///
[782]1227    /// \warning A removed node could become valid again if new nodes are
[149]1228    /// added to the graph.
1229    bool valid(Node n) const { return Parent::valid(n); }
[782]1230    /// Edge validity check
1231
1232    /// This function gives back \c true if the given edge is valid,
1233    /// i.e. it is a real edge of the graph.
1234    ///
1235    /// \warning A removed edge could become valid again if new edges are
1236    /// added to the graph.
1237    bool valid(Edge e) const { return Parent::valid(e); }
[149]1238    /// Arc validity check
1239
[782]1240    /// This function gives back \c true if the given arc is valid,
1241    /// i.e. it is a real arc of the graph.
[149]1242    ///
[782]1243    /// \warning A removed arc could become valid again if new edges are
[149]1244    /// added to the graph.
1245    bool valid(Arc a) const { return Parent::valid(a); }
1246
[782]1247    /// \brief Change the first node of an edge.
[149]1248    ///
[782]1249    /// This function changes the first node of the given edge \c e to \c n.
[57]1250    ///
[782]1251    ///\note \c EdgeIt and \c ArcIt iterators referencing the
1252    ///changed edge are invalidated and all other iterators whose
1253    ///base node is the changed node are also invalidated.
[73]1254    ///
1255    ///\warning This functionality cannot be used together with the
1256    ///Snapshot feature.
[235]1257    void changeU(Edge e, Node n) {
1258      Parent::changeU(e,n);
[209]1259    }
[782]1260    /// \brief Change the second node of an edge.
[57]1261    ///
[782]1262    /// This function changes the second node of the given edge \c e to \c n.
[57]1263    ///
[782]1264    ///\note \c EdgeIt iterators referencing the changed edge remain
1265    ///valid, however \c ArcIt iterators referencing the changed edge and
1266    ///all other iterators whose base node is the changed node are also
1267    ///invalidated.
[73]1268    ///
1269    ///\warning This functionality cannot be used together with the
1270    ///Snapshot feature.
[235]1271    void changeV(Edge e, Node n) {
1272      Parent::changeV(e,n);
[57]1273    }
[782]1274
[57]1275    /// \brief Contract two nodes.
1276    ///
[782]1277    /// This function contracts the given two nodes.
1278    /// Node \c b is removed, but instead of deleting
1279    /// its incident edges, they are joined to node \c a.
1280    /// If the last parameter \c r is \c true (this is the default value),
1281    /// then the newly created loops are removed.
[57]1282    ///
[782]1283    /// \note The moved edges are joined to node \c a using changeU()
1284    /// or changeV(), thus all edge and arc iterators whose base node is
1285    /// \c b are invalidated.
1286    /// Moreover all iterators referencing node \c b or the removed
1287    /// loops are also invalidated. Other iterators remain valid.
[73]1288    ///
1289    ///\warning This functionality cannot be used together with the
1290    ///Snapshot feature.
[57]1291    void contract(Node a, Node b, bool r = true) {
[73]1292      for(IncEdgeIt e(*this, b); e!=INVALID;) {
[209]1293        IncEdgeIt f = e; ++f;
1294        if (r && runningNode(e) == a) {
1295          erase(e);
[235]1296        } else if (u(e) == b) {
1297          changeU(e, a);
[209]1298        } else {
[235]1299          changeV(e, a);
[209]1300        }
1301        e = f;
[57]1302      }
1303      erase(b);
1304    }
1305
[782]1306    ///Clear the graph.
1307
1308    ///This function erases all nodes and arcs from the graph.
1309    ///
1310    void clear() {
1311      Parent::clear();
1312    }
[57]1313
[73]1314    /// \brief Class to make a snapshot of the graph and restore
1315    /// it later.
[57]1316    ///
[73]1317    /// Class to make a snapshot of the graph and restore it later.
[57]1318    ///
1319    /// The newly added nodes and edges can be removed
1320    /// using the restore() function.
1321    ///
[782]1322    /// \note After a state is restored, you cannot restore a later state,
1323    /// i.e. you cannot add the removed nodes and edges again using
1324    /// another Snapshot instance.
1325    ///
1326    /// \warning Node and edge deletions and other modifications
1327    /// (e.g. changing the end-nodes of edges or contracting nodes)
1328    /// cannot be restored. These events invalidate the snapshot.
1329    /// However the edges and nodes that were added to the graph after
1330    /// making the current snapshot can be removed without invalidating it.
[57]1331    class Snapshot {
1332    protected:
1333
1334      typedef Parent::NodeNotifier NodeNotifier;
1335
1336      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1337      public:
1338
1339        NodeObserverProxy(Snapshot& _snapshot)
1340          : snapshot(_snapshot) {}
1341
1342        using NodeNotifier::ObserverBase::attach;
1343        using NodeNotifier::ObserverBase::detach;
1344        using NodeNotifier::ObserverBase::attached;
[209]1345
[57]1346      protected:
[209]1347
[57]1348        virtual void add(const Node& node) {
1349          snapshot.addNode(node);
1350        }
1351        virtual void add(const std::vector<Node>& nodes) {
1352          for (int i = nodes.size() - 1; i >= 0; ++i) {
1353            snapshot.addNode(nodes[i]);
1354          }
1355        }
1356        virtual void erase(const Node& node) {
1357          snapshot.eraseNode(node);
1358        }
1359        virtual void erase(const std::vector<Node>& nodes) {
1360          for (int i = 0; i < int(nodes.size()); ++i) {
1361            snapshot.eraseNode(nodes[i]);
1362          }
1363        }
1364        virtual void build() {
1365          Node node;
1366          std::vector<Node> nodes;
[209]1367          for (notifier()->first(node); node != INVALID;
[57]1368               notifier()->next(node)) {
1369            nodes.push_back(node);
1370          }
1371          for (int i = nodes.size() - 1; i >= 0; --i) {
1372            snapshot.addNode(nodes[i]);
1373          }
1374        }
1375        virtual void clear() {
1376          Node node;
[209]1377          for (notifier()->first(node); node != INVALID;
[57]1378               notifier()->next(node)) {
1379            snapshot.eraseNode(node);
1380          }
1381        }
1382
1383        Snapshot& snapshot;
1384      };
1385
1386      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1387      public:
1388
1389        EdgeObserverProxy(Snapshot& _snapshot)
1390          : snapshot(_snapshot) {}
1391
1392        using EdgeNotifier::ObserverBase::attach;
1393        using EdgeNotifier::ObserverBase::detach;
1394        using EdgeNotifier::ObserverBase::attached;
[209]1395
[57]1396      protected:
1397
[73]1398        virtual void add(const Edge& edge) {
1399          snapshot.addEdge(edge);
[57]1400        }
[73]1401        virtual void add(const std::vector<Edge>& edges) {
1402          for (int i = edges.size() - 1; i >= 0; ++i) {
1403            snapshot.addEdge(edges[i]);
[57]1404          }
1405        }
[73]1406        virtual void erase(const Edge& edge) {
1407          snapshot.eraseEdge(edge);
[57]1408        }
[73]1409        virtual void erase(const std::vector<Edge>& edges) {
1410          for (int i = 0; i < int(edges.size()); ++i) {
1411            snapshot.eraseEdge(edges[i]);
[57]1412          }
1413        }
1414        virtual void build() {
[73]1415          Edge edge;
1416          std::vector<Edge> edges;
[209]1417          for (notifier()->first(edge); edge != INVALID;
[73]1418               notifier()->next(edge)) {
1419            edges.push_back(edge);
[57]1420          }
[73]1421          for (int i = edges.size() - 1; i >= 0; --i) {
1422            snapshot.addEdge(edges[i]);
[57]1423          }
1424        }
1425        virtual void clear() {
[73]1426          Edge edge;
[209]1427          for (notifier()->first(edge); edge != INVALID;
[73]1428               notifier()->next(edge)) {
1429            snapshot.eraseEdge(edge);
[57]1430          }
1431        }
1432
1433        Snapshot& snapshot;
1434      };
[73]1435
1436      ListGraph *graph;
[57]1437
1438      NodeObserverProxy node_observer_proxy;
[73]1439      EdgeObserverProxy edge_observer_proxy;
[57]1440
1441      std::list<Node> added_nodes;
[73]1442      std::list<Edge> added_edges;
[57]1443
1444
1445      void addNode(const Node& node) {
[209]1446        added_nodes.push_front(node);
[57]1447      }
1448      void eraseNode(const Node& node) {
[209]1449        std::list<Node>::iterator it =
[57]1450          std::find(added_nodes.begin(), added_nodes.end(), node);
1451        if (it == added_nodes.end()) {
1452          clear();
[73]1453          edge_observer_proxy.detach();
[57]1454          throw NodeNotifier::ImmediateDetach();
1455        } else {
1456          added_nodes.erase(it);
1457        }
1458      }
1459
[73]1460      void addEdge(const Edge& edge) {
[209]1461        added_edges.push_front(edge);
[57]1462      }
[73]1463      void eraseEdge(const Edge& edge) {
[209]1464        std::list<Edge>::iterator it =
[73]1465          std::find(added_edges.begin(), added_edges.end(), edge);
1466        if (it == added_edges.end()) {
[57]1467          clear();
1468          node_observer_proxy.detach();
1469          throw EdgeNotifier::ImmediateDetach();
1470        } else {
[73]1471          added_edges.erase(it);
1472        }
[57]1473      }
1474
[73]1475      void attach(ListGraph &_graph) {
[209]1476        graph = &_graph;
1477        node_observer_proxy.attach(graph->notifier(Node()));
[73]1478        edge_observer_proxy.attach(graph->notifier(Edge()));
[57]1479      }
[209]1480
[57]1481      void detach() {
[209]1482        node_observer_proxy.detach();
1483        edge_observer_proxy.detach();
[57]1484      }
1485
1486      bool attached() const {
1487        return node_observer_proxy.attached();
1488      }
1489
1490      void clear() {
1491        added_nodes.clear();
[209]1492        added_edges.clear();
[57]1493      }
1494
1495    public:
1496
1497      /// \brief Default constructor.
1498      ///
1499      /// Default constructor.
[782]1500      /// You have to call save() to actually make a snapshot.
[209]1501      Snapshot()
1502        : graph(0), node_observer_proxy(*this),
[73]1503          edge_observer_proxy(*this) {}
[209]1504
[57]1505      /// \brief Constructor that immediately makes a snapshot.
[209]1506      ///
[782]1507      /// This constructor immediately makes a snapshot of the given graph.
1508      Snapshot(ListGraph &gr)
[209]1509        : node_observer_proxy(*this),
[73]1510          edge_observer_proxy(*this) {
[782]1511        attach(gr);
[57]1512      }
[209]1513
[57]1514      /// \brief Make a snapshot.
1515      ///
[782]1516      /// This function makes a snapshot of the given graph.
1517      /// It can be called more than once. In case of a repeated
[57]1518      /// call, the previous snapshot gets lost.
[782]1519      void save(ListGraph &gr) {
[57]1520        if (attached()) {
1521          detach();
1522          clear();
1523        }
[782]1524        attach(gr);
[57]1525      }
[209]1526
[57]1527      /// \brief Undo the changes until the last snapshot.
[782]1528      ///
1529      /// This function undos the changes until the last snapshot
1530      /// created by save() or Snapshot(ListGraph&).
[57]1531      void restore() {
[209]1532        detach();
1533        for(std::list<Edge>::iterator it = added_edges.begin();
[73]1534            it != added_edges.end(); ++it) {
[209]1535          graph->erase(*it);
1536        }
1537        for(std::list<Node>::iterator it = added_nodes.begin();
[57]1538            it != added_nodes.end(); ++it) {
[209]1539          graph->erase(*it);
1540        }
[57]1541        clear();
1542      }
1543
[782]1544      /// \brief Returns \c true if the snapshot is valid.
[57]1545      ///
[782]1546      /// This function returns \c true if the snapshot is valid.
[57]1547      bool valid() const {
1548        return attached();
1549      }
1550    };
1551  };
[209]1552
1553  /// @}
[57]1554} //namespace lemon
[209]1555
[57]1556
1557#endif
Note: See TracBrowser for help on using the repository browser.