COIN-OR::LEMON - Graph Library

source: lemon/lemon/list_graph.h @ 1288:dd5b5d96b657

Last change on this file since 1288:dd5b5d96b657 was 956:141f9c0db4a3, checked in by Alpar Juttner <alpar@…>, 10 years ago

Unify the sources (#339)

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