More exact concept checking for map concepts.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_LIST_GRAPH_H
20 #define LEMON_LIST_GRAPH_H
24 ///\brief ListDigraph, ListGraph classes.
26 #include <lemon/bits/graph_extender.h>
33 class ListDigraphBase {
37 int first_in, first_out;
43 int prev_in, prev_out;
44 int next_in, next_out;
47 std::vector<NodeT> nodes;
53 std::vector<ArcT> arcs;
59 typedef ListDigraphBase Digraph;
62 friend class ListDigraphBase;
66 explicit Node(int pid) { id = pid;}
70 Node (Invalid) { id = -1; }
71 bool operator==(const Node& node) const {return id == node.id;}
72 bool operator!=(const Node& node) const {return id != node.id;}
73 bool operator<(const Node& node) const {return id < node.id;}
77 friend class ListDigraphBase;
81 explicit Arc(int pid) { id = pid;}
85 Arc (Invalid) { id = -1; }
86 bool operator==(const Arc& arc) const {return id == arc.id;}
87 bool operator!=(const Arc& arc) const {return id != arc.id;}
88 bool operator<(const Arc& arc) const {return id < arc.id;}
94 : nodes(), first_node(-1),
95 first_free_node(-1), arcs(), first_free_arc(-1) {}
98 int maxNodeId() const { return nodes.size()-1; }
99 int maxArcId() const { return arcs.size()-1; }
101 Node source(Arc e) const { return Node(arcs[e.id].source); }
102 Node target(Arc e) const { return Node(arcs[e.id].target); }
105 void first(Node& node) const {
106 node.id = first_node;
109 void next(Node& node) const {
110 node.id = nodes[node.id].next;
114 void first(Arc& arc) const {
117 n!=-1 && nodes[n].first_in == -1;
119 arc.id = (n == -1) ? -1 : nodes[n].first_in;
122 void next(Arc& arc) const {
123 if (arcs[arc.id].next_in != -1) {
124 arc.id = arcs[arc.id].next_in;
127 for(n = nodes[arcs[arc.id].target].next;
128 n!=-1 && nodes[n].first_in == -1;
130 arc.id = (n == -1) ? -1 : nodes[n].first_in;
134 void firstOut(Arc &e, const Node& v) const {
135 e.id = nodes[v.id].first_out;
137 void nextOut(Arc &e) const {
138 e.id=arcs[e.id].next_out;
141 void firstIn(Arc &e, const Node& v) const {
142 e.id = nodes[v.id].first_in;
144 void nextIn(Arc &e) const {
145 e.id=arcs[e.id].next_in;
149 static int id(Node v) { return v.id; }
150 static int id(Arc e) { return e.id; }
152 static Node nodeFromId(int id) { return Node(id);}
153 static Arc arcFromId(int id) { return Arc(id);}
158 if(first_free_node==-1) {
160 nodes.push_back(NodeT());
163 first_free_node = nodes[n].next;
166 nodes[n].next = first_node;
167 if(first_node != -1) nodes[first_node].prev = n;
171 nodes[n].first_in = nodes[n].first_out = -1;
176 Arc addArc(Node u, Node v) {
179 if (first_free_arc == -1) {
181 arcs.push_back(ArcT());
184 first_free_arc = arcs[n].next_in;
187 arcs[n].source = u.id;
188 arcs[n].target = v.id;
190 arcs[n].next_out = nodes[u.id].first_out;
191 if(nodes[u.id].first_out != -1) {
192 arcs[nodes[u.id].first_out].prev_out = n;
195 arcs[n].next_in = nodes[v.id].first_in;
196 if(nodes[v.id].first_in != -1) {
197 arcs[nodes[v.id].first_in].prev_in = n;
200 arcs[n].prev_in = arcs[n].prev_out = -1;
202 nodes[u.id].first_out = nodes[v.id].first_in = n;
207 void erase(const Node& node) {
210 if(nodes[n].next != -1) {
211 nodes[nodes[n].next].prev = nodes[n].prev;
214 if(nodes[n].prev != -1) {
215 nodes[nodes[n].prev].next = nodes[n].next;
217 first_node = nodes[n].next;
220 nodes[n].next = first_free_node;
225 void erase(const Arc& arc) {
228 if(arcs[n].next_in!=-1) {
229 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
232 if(arcs[n].prev_in!=-1) {
233 arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
235 nodes[arcs[n].target].first_in = arcs[n].next_in;
239 if(arcs[n].next_out!=-1) {
240 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
243 if(arcs[n].prev_out!=-1) {
244 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
246 nodes[arcs[n].source].first_out = arcs[n].next_out;
249 arcs[n].next_in = first_free_arc;
257 first_node = first_free_node = first_free_arc = -1;
261 void changeTarget(Arc e, Node n)
263 if(arcs[e.id].next_in != -1)
264 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
265 if(arcs[e.id].prev_in != -1)
266 arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
267 else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
268 if (nodes[n.id].first_in != -1) {
269 arcs[nodes[n.id].first_in].prev_in = e.id;
271 arcs[e.id].target = n.id;
272 arcs[e.id].prev_in = -1;
273 arcs[e.id].next_in = nodes[n.id].first_in;
274 nodes[n.id].first_in = e.id;
276 void changeSource(Arc e, Node n)
278 if(arcs[e.id].next_out != -1)
279 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
280 if(arcs[e.id].prev_out != -1)
281 arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
282 else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
283 if (nodes[n.id].first_out != -1) {
284 arcs[nodes[n.id].first_out].prev_out = e.id;
286 arcs[e.id].source = n.id;
287 arcs[e.id].prev_out = -1;
288 arcs[e.id].next_out = nodes[n.id].first_out;
289 nodes[n.id].first_out = e.id;
294 typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
296 /// \addtogroup graphs
299 ///A general directed graph structure.
301 ///\ref ListDigraph is a simple and fast <em>directed graph</em>
302 ///implementation based on static linked lists that are stored in
303 ///\c std::vector structures.
305 ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
306 ///also provides several useful additional functionalities.
307 ///Most of the member functions and nested classes are documented
308 ///only in the concept class.
310 ///An important extra feature of this digraph implementation is that
311 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
313 ///\sa concepts::Digraph
315 class ListDigraph : public ExtendedListDigraphBase {
317 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
319 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
321 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
322 ///\brief Assignment of ListDigraph to another one is \e not allowed.
323 ///Use copyDigraph() instead.
325 ///Assignment of ListDigraph to another one is \e not allowed.
326 ///Use copyDigraph() instead.
327 void operator=(const ListDigraph &) {}
330 typedef ExtendedListDigraphBase Parent;
338 ///Add a new node to the digraph.
340 ///Add a new node to the digraph.
341 ///\return the new node.
342 Node addNode() { return Parent::addNode(); }
344 ///Add a new arc to the digraph.
346 ///Add a new arc to the digraph with source node \c s
347 ///and target node \c t.
348 ///\return the new arc.
349 Arc addArc(const Node& s, const Node& t) {
350 return Parent::addArc(s, t);
353 /// Change the target of \c e to \c n
355 /// Change the target of \c e to \c n
357 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
358 ///the changed arc remain valid. However <tt>InArcIt</tt>s are
361 ///\warning This functionality cannot be used together with the Snapshot
363 void changeTarget(Arc e, Node n) {
364 Parent::changeTarget(e,n);
366 /// Change the source of \c e to \c n
368 /// Change the source of \c e to \c n
370 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
371 ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
374 ///\warning This functionality cannot be used together with the Snapshot
376 void changeSource(Arc e, Node n) {
377 Parent::changeSource(e,n);
380 /// Invert the direction of an arc.
382 ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
383 ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
386 ///\warning This functionality cannot be used together with the Snapshot
388 void reverseArc(Arc e) {
390 changeTarget(e,source(e));
394 /// Reserve memory for nodes.
396 /// Using this function it is possible to avoid the superfluous memory
397 /// allocation: if you know that the digraph you want to build will
398 /// be very large (e.g. it will contain millions of nodes and/or arcs)
399 /// then it is worth reserving space for this amount before starting
400 /// to build the digraph.
402 void reserveNode(int n) { nodes.reserve(n); };
404 /// Reserve memory for arcs.
406 /// Using this function it is possible to avoid the superfluous memory
407 /// allocation: if you know that the digraph you want to build will
408 /// be very large (e.g. it will contain millions of nodes and/or arcs)
409 /// then it is worth reserving space for this amount before starting
410 /// to build the digraph.
412 void reserveArc(int m) { arcs.reserve(m); };
414 ///Contract two nodes.
416 ///This function contracts two nodes.
417 ///Node \p b will be removed but instead of deleting
418 ///incident arcs, they will be joined to \p a.
419 ///The last parameter \p r controls whether to remove loops. \c true
420 ///means that loops will be removed.
422 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
423 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
424 ///may be invalidated.
426 ///\warning This functionality cannot be used together with the Snapshot
428 void contract(Node a, Node b, bool r = true)
430 for(OutArcIt e(*this,b);e!=INVALID;) {
433 if(r && target(e)==a) erase(e);
434 else changeSource(e,a);
437 for(InArcIt e(*this,b);e!=INVALID;) {
440 if(r && source(e)==a) erase(e);
441 else changeTarget(e,a);
449 ///This function splits a node. First a new node is added to the digraph,
450 ///then the source of each outgoing arc of \c n is moved to this new node.
451 ///If \c connect is \c true (this is the default value), then a new arc
452 ///from \c n to the newly created node is also added.
453 ///\return The newly created node.
455 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
456 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
459 ///\warning This functionality cannot be used together with the
462 ///\todo It could be implemented in a bit faster way.
463 Node split(Node n, bool connect = true) {
465 for(OutArcIt e(*this,n);e!=INVALID;) {
471 if (connect) addArc(n,b);
477 ///This function splits an arc. First a new node \c b is added to
478 ///the digraph, then the original arc is re-targeted to \c
479 ///b. Finally an arc from \c b to the original target is added.
481 ///\return The newly created node.
483 ///\warning This functionality cannot be used together with the
492 /// \brief Class to make a snapshot of the digraph and restore
495 /// Class to make a snapshot of the digraph and restore it later.
497 /// The newly added nodes and arcs can be removed using the
498 /// restore() function.
500 /// \warning Arc and node deletions and other modifications (e.g.
501 /// contracting, splitting, reversing arcs or nodes) cannot be
502 /// restored. These events invalidate the snapshot.
506 typedef Parent::NodeNotifier NodeNotifier;
508 class NodeObserverProxy : public NodeNotifier::ObserverBase {
511 NodeObserverProxy(Snapshot& _snapshot)
512 : snapshot(_snapshot) {}
514 using NodeNotifier::ObserverBase::attach;
515 using NodeNotifier::ObserverBase::detach;
516 using NodeNotifier::ObserverBase::attached;
520 virtual void add(const Node& node) {
521 snapshot.addNode(node);
523 virtual void add(const std::vector<Node>& nodes) {
524 for (int i = nodes.size() - 1; i >= 0; ++i) {
525 snapshot.addNode(nodes[i]);
528 virtual void erase(const Node& node) {
529 snapshot.eraseNode(node);
531 virtual void erase(const std::vector<Node>& nodes) {
532 for (int i = 0; i < int(nodes.size()); ++i) {
533 snapshot.eraseNode(nodes[i]);
536 virtual void build() {
538 std::vector<Node> nodes;
539 for (notifier()->first(node); node != INVALID;
540 notifier()->next(node)) {
541 nodes.push_back(node);
543 for (int i = nodes.size() - 1; i >= 0; --i) {
544 snapshot.addNode(nodes[i]);
547 virtual void clear() {
549 for (notifier()->first(node); node != INVALID;
550 notifier()->next(node)) {
551 snapshot.eraseNode(node);
558 class ArcObserverProxy : public ArcNotifier::ObserverBase {
561 ArcObserverProxy(Snapshot& _snapshot)
562 : snapshot(_snapshot) {}
564 using ArcNotifier::ObserverBase::attach;
565 using ArcNotifier::ObserverBase::detach;
566 using ArcNotifier::ObserverBase::attached;
570 virtual void add(const Arc& arc) {
571 snapshot.addArc(arc);
573 virtual void add(const std::vector<Arc>& arcs) {
574 for (int i = arcs.size() - 1; i >= 0; ++i) {
575 snapshot.addArc(arcs[i]);
578 virtual void erase(const Arc& arc) {
579 snapshot.eraseArc(arc);
581 virtual void erase(const std::vector<Arc>& arcs) {
582 for (int i = 0; i < int(arcs.size()); ++i) {
583 snapshot.eraseArc(arcs[i]);
586 virtual void build() {
588 std::vector<Arc> arcs;
589 for (notifier()->first(arc); arc != INVALID;
590 notifier()->next(arc)) {
593 for (int i = arcs.size() - 1; i >= 0; --i) {
594 snapshot.addArc(arcs[i]);
597 virtual void clear() {
599 for (notifier()->first(arc); arc != INVALID;
600 notifier()->next(arc)) {
601 snapshot.eraseArc(arc);
608 ListDigraph *digraph;
610 NodeObserverProxy node_observer_proxy;
611 ArcObserverProxy arc_observer_proxy;
613 std::list<Node> added_nodes;
614 std::list<Arc> added_arcs;
617 void addNode(const Node& node) {
618 added_nodes.push_front(node);
620 void eraseNode(const Node& node) {
621 std::list<Node>::iterator it =
622 std::find(added_nodes.begin(), added_nodes.end(), node);
623 if (it == added_nodes.end()) {
625 arc_observer_proxy.detach();
626 throw NodeNotifier::ImmediateDetach();
628 added_nodes.erase(it);
632 void addArc(const Arc& arc) {
633 added_arcs.push_front(arc);
635 void eraseArc(const Arc& arc) {
636 std::list<Arc>::iterator it =
637 std::find(added_arcs.begin(), added_arcs.end(), arc);
638 if (it == added_arcs.end()) {
640 node_observer_proxy.detach();
641 throw ArcNotifier::ImmediateDetach();
643 added_arcs.erase(it);
647 void attach(ListDigraph &_digraph) {
649 node_observer_proxy.attach(digraph->notifier(Node()));
650 arc_observer_proxy.attach(digraph->notifier(Arc()));
654 node_observer_proxy.detach();
655 arc_observer_proxy.detach();
658 bool attached() const {
659 return node_observer_proxy.attached();
669 /// \brief Default constructor.
671 /// Default constructor.
672 /// To actually make a snapshot you must call save().
674 : digraph(0), node_observer_proxy(*this),
675 arc_observer_proxy(*this) {}
677 /// \brief Constructor that immediately makes a snapshot.
679 /// This constructor immediately makes a snapshot of the digraph.
680 /// \param _digraph The digraph we make a snapshot of.
681 Snapshot(ListDigraph &_digraph)
682 : node_observer_proxy(*this),
683 arc_observer_proxy(*this) {
687 /// \brief Make a snapshot.
689 /// Make a snapshot of the digraph.
691 /// This function can be called more than once. In case of a repeated
692 /// call, the previous snapshot gets lost.
693 /// \param _digraph The digraph we make the snapshot of.
694 void save(ListDigraph &_digraph) {
702 /// \brief Undo the changes until the last snapshot.
704 /// Undo the changes until the last snapshot created by save().
707 for(std::list<Arc>::iterator it = added_arcs.begin();
708 it != added_arcs.end(); ++it) {
711 for(std::list<Node>::iterator it = added_nodes.begin();
712 it != added_nodes.end(); ++it) {
718 /// \brief Gives back true when the snapshot is valid.
720 /// Gives back true when the snapshot is valid.
730 class ListGraphBase {
741 int prev_out, next_out;
744 std::vector<NodeT> nodes;
750 std::vector<ArcT> arcs;
756 typedef ListGraphBase Digraph;
763 friend class ListGraphBase;
767 explicit Node(int pid) { id = pid;}
771 Node (Invalid) { id = -1; }
772 bool operator==(const Node& node) const {return id == node.id;}
773 bool operator!=(const Node& node) const {return id != node.id;}
774 bool operator<(const Node& node) const {return id < node.id;}
778 friend class ListGraphBase;
782 explicit Edge(int pid) { id = pid;}
786 Edge (Invalid) { id = -1; }
787 bool operator==(const Edge& edge) const {return id == edge.id;}
788 bool operator!=(const Edge& edge) const {return id != edge.id;}
789 bool operator<(const Edge& edge) const {return id < edge.id;}
793 friend class ListGraphBase;
797 explicit Arc(int pid) { id = pid;}
800 operator Edge() const { return edgeFromId(id / 2); }
803 Arc (Invalid) { id = -1; }
804 bool operator==(const Arc& arc) const {return id == arc.id;}
805 bool operator!=(const Arc& arc) const {return id != arc.id;}
806 bool operator<(const Arc& arc) const {return id < arc.id;}
812 : nodes(), first_node(-1),
813 first_free_node(-1), arcs(), first_free_arc(-1) {}
816 int maxNodeId() const { return nodes.size()-1; }
817 int maxEdgeId() const { return arcs.size() / 2 - 1; }
818 int maxArcId() const { return arcs.size()-1; }
820 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
821 Node target(Arc e) const { return Node(arcs[e.id].target); }
823 Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
824 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
826 static bool direction(Arc e) {
827 return (e.id & 1) == 1;
830 static Arc direct(Edge e, bool d) {
831 return Arc(e.id * 2 + (d ? 1 : 0));
834 void first(Node& node) const {
835 node.id = first_node;
838 void next(Node& node) const {
839 node.id = nodes[node.id].next;
842 void first(Arc& e) const {
844 while (n != -1 && nodes[n].first_out == -1) {
847 e.id = (n == -1) ? -1 : nodes[n].first_out;
850 void next(Arc& e) const {
851 if (arcs[e.id].next_out != -1) {
852 e.id = arcs[e.id].next_out;
854 int n = nodes[arcs[e.id ^ 1].target].next;
855 while(n != -1 && nodes[n].first_out == -1) {
858 e.id = (n == -1) ? -1 : nodes[n].first_out;
862 void first(Edge& e) const {
865 e.id = nodes[n].first_out;
866 while ((e.id & 1) != 1) {
867 e.id = arcs[e.id].next_out;
878 void next(Edge& e) const {
879 int n = arcs[e.id * 2].target;
880 e.id = arcs[(e.id * 2) | 1].next_out;
881 while ((e.id & 1) != 1) {
882 e.id = arcs[e.id].next_out;
890 e.id = nodes[n].first_out;
891 while ((e.id & 1) != 1) {
892 e.id = arcs[e.id].next_out;
903 void firstOut(Arc &e, const Node& v) const {
904 e.id = nodes[v.id].first_out;
906 void nextOut(Arc &e) const {
907 e.id = arcs[e.id].next_out;
910 void firstIn(Arc &e, const Node& v) const {
911 e.id = ((nodes[v.id].first_out) ^ 1);
912 if (e.id == -2) e.id = -1;
914 void nextIn(Arc &e) const {
915 e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
916 if (e.id == -2) e.id = -1;
919 void firstInc(Edge &e, bool& d, const Node& v) const {
920 int a = nodes[v.id].first_out;
929 void nextInc(Edge &e, bool& d) const {
930 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
940 static int id(Node v) { return v.id; }
941 static int id(Arc e) { return e.id; }
942 static int id(Edge e) { return e.id; }
944 static Node nodeFromId(int id) { return Node(id);}
945 static Arc arcFromId(int id) { return Arc(id);}
946 static Edge edgeFromId(int id) { return Edge(id);}
951 if(first_free_node==-1) {
953 nodes.push_back(NodeT());
956 first_free_node = nodes[n].next;
959 nodes[n].next = first_node;
960 if (first_node != -1) nodes[first_node].prev = n;
964 nodes[n].first_out = -1;
969 Edge addEdge(Node u, Node v) {
972 if (first_free_arc == -1) {
974 arcs.push_back(ArcT());
975 arcs.push_back(ArcT());
978 first_free_arc = arcs[n].next_out;
981 arcs[n].target = u.id;
982 arcs[n | 1].target = v.id;
984 arcs[n].next_out = nodes[v.id].first_out;
985 if (nodes[v.id].first_out != -1) {
986 arcs[nodes[v.id].first_out].prev_out = n;
988 arcs[n].prev_out = -1;
989 nodes[v.id].first_out = n;
991 arcs[n | 1].next_out = nodes[u.id].first_out;
992 if (nodes[u.id].first_out != -1) {
993 arcs[nodes[u.id].first_out].prev_out = (n | 1);
995 arcs[n | 1].prev_out = -1;
996 nodes[u.id].first_out = (n | 1);
1001 void erase(const Node& node) {
1004 if(nodes[n].next != -1) {
1005 nodes[nodes[n].next].prev = nodes[n].prev;
1008 if(nodes[n].prev != -1) {
1009 nodes[nodes[n].prev].next = nodes[n].next;
1011 first_node = nodes[n].next;
1014 nodes[n].next = first_free_node;
1015 first_free_node = n;
1019 void erase(const Edge& edge) {
1020 int n = edge.id * 2;
1022 if (arcs[n].next_out != -1) {
1023 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1026 if (arcs[n].prev_out != -1) {
1027 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1029 nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1032 if (arcs[n | 1].next_out != -1) {
1033 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1036 if (arcs[n | 1].prev_out != -1) {
1037 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1039 nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1042 arcs[n].next_out = first_free_arc;
1050 first_node = first_free_node = first_free_arc = -1;
1055 void changeTarget(Edge e, Node n) {
1056 if(arcs[2 * e.id].next_out != -1) {
1057 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1059 if(arcs[2 * e.id].prev_out != -1) {
1060 arcs[arcs[2 * e.id].prev_out].next_out =
1061 arcs[2 * e.id].next_out;
1063 nodes[arcs[(2 * e.id) | 1].target].first_out =
1064 arcs[2 * e.id].next_out;
1067 if (nodes[n.id].first_out != -1) {
1068 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1070 arcs[(2 * e.id) | 1].target = n.id;
1071 arcs[2 * e.id].prev_out = -1;
1072 arcs[2 * e.id].next_out = nodes[n.id].first_out;
1073 nodes[n.id].first_out = 2 * e.id;
1076 void changeSource(Edge e, Node n) {
1077 if(arcs[(2 * e.id) | 1].next_out != -1) {
1078 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1079 arcs[(2 * e.id) | 1].prev_out;
1081 if(arcs[(2 * e.id) | 1].prev_out != -1) {
1082 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1083 arcs[(2 * e.id) | 1].next_out;
1085 nodes[arcs[2 * e.id].target].first_out =
1086 arcs[(2 * e.id) | 1].next_out;
1089 if (nodes[n.id].first_out != -1) {
1090 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1092 arcs[2 * e.id].target = n.id;
1093 arcs[(2 * e.id) | 1].prev_out = -1;
1094 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1095 nodes[n.id].first_out = ((2 * e.id) | 1);
1100 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1103 /// \addtogroup graphs
1106 ///A general undirected graph structure.
1108 ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1109 ///implementation based on static linked lists that are stored in
1110 ///\c std::vector structures.
1112 ///It conforms to the \ref concepts::Graph "Graph concept" and it
1113 ///also provides several useful additional functionalities.
1114 ///Most of the member functions and nested classes are documented
1115 ///only in the concept class.
1117 ///An important extra feature of this graph implementation is that
1118 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1120 ///\sa concepts::Graph
1122 class ListGraph : public ExtendedListGraphBase {
1124 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1126 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1128 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
1129 ///\brief Assignment of ListGraph to another one is \e not allowed.
1130 ///Use copyGraph() instead.
1132 ///Assignment of ListGraph to another one is \e not allowed.
1133 ///Use copyGraph() instead.
1134 void operator=(const ListGraph &) {}
1142 typedef ExtendedListGraphBase Parent;
1144 typedef Parent::OutArcIt IncEdgeIt;
1146 /// \brief Add a new node to the graph.
1148 /// Add a new node to the graph.
1149 /// \return the new node.
1150 Node addNode() { return Parent::addNode(); }
1152 /// \brief Add a new edge to the graph.
1154 /// Add a new edge to the graph with source node \c s
1155 /// and target node \c t.
1156 /// \return the new edge.
1157 Edge addEdge(const Node& s, const Node& t) {
1158 return Parent::addEdge(s, t);
1160 /// \brief Change the source of \c e to \c n
1162 /// This function changes the source of \c e to \c n.
1164 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1165 ///referencing the changed arc remain
1166 ///valid. However <tt>OutArcIt</tt>s are invalidated.
1168 ///\warning This functionality cannot be used together with the
1169 ///Snapshot feature.
1170 void changeSource(Edge e, Node n) {
1171 Parent::changeSource(e,n);
1173 /// \brief Change the target of \c e to \c n
1175 /// This function changes the target of \c e to \c n.
1177 /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1178 /// valid. However the other iterators may be invalidated.
1180 ///\warning This functionality cannot be used together with the
1181 ///Snapshot feature.
1182 void changeTarget(Edge e, Node n) {
1183 Parent::changeTarget(e,n);
1185 /// \brief Change the source of \c e to \c n
1187 /// This function changes the source of \c e to \c n.
1188 /// It also changes the proper node of the represented edge.
1190 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1191 ///referencing the changed arc remain
1192 ///valid. However <tt>OutArcIt</tt>s are invalidated.
1194 ///\warning This functionality cannot be used together with the
1195 ///Snapshot feature.
1196 void changeSource(Arc e, Node n) {
1197 if (Parent::direction(e)) {
1198 Parent::changeSource(e,n);
1200 Parent::changeTarget(e,n);
1203 /// \brief Change the target of \c e to \c n
1205 /// This function changes the target of \c e to \c n.
1206 /// It also changes the proper node of the represented edge.
1208 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
1209 ///referencing the changed arc remain
1210 ///valid. However <tt>InArcIt</tt>s are invalidated.
1212 ///\warning This functionality cannot be used together with the
1213 ///Snapshot feature.
1214 void changeTarget(Arc e, Node n) {
1215 if (Parent::direction(e)) {
1216 Parent::changeTarget(e,n);
1218 Parent::changeSource(e,n);
1221 /// \brief Contract two nodes.
1223 /// This function contracts two nodes.
1224 /// Node \p b will be removed but instead of deleting
1225 /// its neighboring arcs, they will be joined to \p a.
1226 /// The last parameter \p r controls whether to remove loops. \c true
1227 /// means that loops will be removed.
1229 /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1232 ///\warning This functionality cannot be used together with the
1233 ///Snapshot feature.
1234 void contract(Node a, Node b, bool r = true) {
1235 for(IncEdgeIt e(*this, b); e!=INVALID;) {
1236 IncEdgeIt f = e; ++f;
1237 if (r && runningNode(e) == a) {
1239 } else if (source(e) == b) {
1250 /// \brief Class to make a snapshot of the graph and restore
1253 /// Class to make a snapshot of the graph and restore it later.
1255 /// The newly added nodes and edges can be removed
1256 /// using the restore() function.
1258 /// \warning Edge and node deletions and other modifications
1259 /// (e.g. changing nodes of edges, contracting nodes) cannot be
1260 /// restored. These events invalidate the snapshot.
1264 typedef Parent::NodeNotifier NodeNotifier;
1266 class NodeObserverProxy : public NodeNotifier::ObserverBase {
1269 NodeObserverProxy(Snapshot& _snapshot)
1270 : snapshot(_snapshot) {}
1272 using NodeNotifier::ObserverBase::attach;
1273 using NodeNotifier::ObserverBase::detach;
1274 using NodeNotifier::ObserverBase::attached;
1278 virtual void add(const Node& node) {
1279 snapshot.addNode(node);
1281 virtual void add(const std::vector<Node>& nodes) {
1282 for (int i = nodes.size() - 1; i >= 0; ++i) {
1283 snapshot.addNode(nodes[i]);
1286 virtual void erase(const Node& node) {
1287 snapshot.eraseNode(node);
1289 virtual void erase(const std::vector<Node>& nodes) {
1290 for (int i = 0; i < int(nodes.size()); ++i) {
1291 snapshot.eraseNode(nodes[i]);
1294 virtual void build() {
1296 std::vector<Node> nodes;
1297 for (notifier()->first(node); node != INVALID;
1298 notifier()->next(node)) {
1299 nodes.push_back(node);
1301 for (int i = nodes.size() - 1; i >= 0; --i) {
1302 snapshot.addNode(nodes[i]);
1305 virtual void clear() {
1307 for (notifier()->first(node); node != INVALID;
1308 notifier()->next(node)) {
1309 snapshot.eraseNode(node);
1316 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1319 EdgeObserverProxy(Snapshot& _snapshot)
1320 : snapshot(_snapshot) {}
1322 using EdgeNotifier::ObserverBase::attach;
1323 using EdgeNotifier::ObserverBase::detach;
1324 using EdgeNotifier::ObserverBase::attached;
1328 virtual void add(const Edge& edge) {
1329 snapshot.addEdge(edge);
1331 virtual void add(const std::vector<Edge>& edges) {
1332 for (int i = edges.size() - 1; i >= 0; ++i) {
1333 snapshot.addEdge(edges[i]);
1336 virtual void erase(const Edge& edge) {
1337 snapshot.eraseEdge(edge);
1339 virtual void erase(const std::vector<Edge>& edges) {
1340 for (int i = 0; i < int(edges.size()); ++i) {
1341 snapshot.eraseEdge(edges[i]);
1344 virtual void build() {
1346 std::vector<Edge> edges;
1347 for (notifier()->first(edge); edge != INVALID;
1348 notifier()->next(edge)) {
1349 edges.push_back(edge);
1351 for (int i = edges.size() - 1; i >= 0; --i) {
1352 snapshot.addEdge(edges[i]);
1355 virtual void clear() {
1357 for (notifier()->first(edge); edge != INVALID;
1358 notifier()->next(edge)) {
1359 snapshot.eraseEdge(edge);
1368 NodeObserverProxy node_observer_proxy;
1369 EdgeObserverProxy edge_observer_proxy;
1371 std::list<Node> added_nodes;
1372 std::list<Edge> added_edges;
1375 void addNode(const Node& node) {
1376 added_nodes.push_front(node);
1378 void eraseNode(const Node& node) {
1379 std::list<Node>::iterator it =
1380 std::find(added_nodes.begin(), added_nodes.end(), node);
1381 if (it == added_nodes.end()) {
1383 edge_observer_proxy.detach();
1384 throw NodeNotifier::ImmediateDetach();
1386 added_nodes.erase(it);
1390 void addEdge(const Edge& edge) {
1391 added_edges.push_front(edge);
1393 void eraseEdge(const Edge& edge) {
1394 std::list<Edge>::iterator it =
1395 std::find(added_edges.begin(), added_edges.end(), edge);
1396 if (it == added_edges.end()) {
1398 node_observer_proxy.detach();
1399 throw EdgeNotifier::ImmediateDetach();
1401 added_edges.erase(it);
1405 void attach(ListGraph &_graph) {
1407 node_observer_proxy.attach(graph->notifier(Node()));
1408 edge_observer_proxy.attach(graph->notifier(Edge()));
1412 node_observer_proxy.detach();
1413 edge_observer_proxy.detach();
1416 bool attached() const {
1417 return node_observer_proxy.attached();
1421 added_nodes.clear();
1422 added_edges.clear();
1427 /// \brief Default constructor.
1429 /// Default constructor.
1430 /// To actually make a snapshot you must call save().
1432 : graph(0), node_observer_proxy(*this),
1433 edge_observer_proxy(*this) {}
1435 /// \brief Constructor that immediately makes a snapshot.
1437 /// This constructor immediately makes a snapshot of the graph.
1438 /// \param _graph The graph we make a snapshot of.
1439 Snapshot(ListGraph &_graph)
1440 : node_observer_proxy(*this),
1441 edge_observer_proxy(*this) {
1445 /// \brief Make a snapshot.
1447 /// Make a snapshot of the graph.
1449 /// This function can be called more than once. In case of a repeated
1450 /// call, the previous snapshot gets lost.
1451 /// \param _graph The graph we make the snapshot of.
1452 void save(ListGraph &_graph) {
1460 /// \brief Undo the changes until the last snapshot.
1462 /// Undo the changes until the last snapshot created by save().
1465 for(std::list<Edge>::iterator it = added_edges.begin();
1466 it != added_edges.end(); ++it) {
1469 for(std::list<Node>::iterator it = added_nodes.begin();
1470 it != added_nodes.end(); ++it) {
1476 /// \brief Gives back true when the snapshot is valid.
1478 /// Gives back true when the snapshot is valid.
1479 bool valid() const {