Fix compilation error when NDEBUG is defined.
1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
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;
118 n = nodes[n].next) {}
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;
129 n = nodes[n].next) {}
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);}
155 bool valid(Node n) const {
156 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
157 nodes[n.id].prev != -2;
160 bool valid(Arc a) const {
161 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
162 arcs[a.id].prev_in != -2;
168 if(first_free_node==-1) {
170 nodes.push_back(NodeT());
173 first_free_node = nodes[n].next;
176 nodes[n].next = first_node;
177 if(first_node != -1) nodes[first_node].prev = n;
181 nodes[n].first_in = nodes[n].first_out = -1;
186 Arc addArc(Node u, Node v) {
189 if (first_free_arc == -1) {
191 arcs.push_back(ArcT());
194 first_free_arc = arcs[n].next_in;
197 arcs[n].source = u.id;
198 arcs[n].target = v.id;
200 arcs[n].next_out = nodes[u.id].first_out;
201 if(nodes[u.id].first_out != -1) {
202 arcs[nodes[u.id].first_out].prev_out = n;
205 arcs[n].next_in = nodes[v.id].first_in;
206 if(nodes[v.id].first_in != -1) {
207 arcs[nodes[v.id].first_in].prev_in = n;
210 arcs[n].prev_in = arcs[n].prev_out = -1;
212 nodes[u.id].first_out = nodes[v.id].first_in = n;
217 void erase(const Node& node) {
220 if(nodes[n].next != -1) {
221 nodes[nodes[n].next].prev = nodes[n].prev;
224 if(nodes[n].prev != -1) {
225 nodes[nodes[n].prev].next = nodes[n].next;
227 first_node = nodes[n].next;
230 nodes[n].next = first_free_node;
236 void erase(const Arc& arc) {
239 if(arcs[n].next_in!=-1) {
240 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
243 if(arcs[n].prev_in!=-1) {
244 arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
246 nodes[arcs[n].target].first_in = arcs[n].next_in;
250 if(arcs[n].next_out!=-1) {
251 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 if(arcs[n].prev_out!=-1) {
255 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
257 nodes[arcs[n].source].first_out = arcs[n].next_out;
260 arcs[n].next_in = first_free_arc;
262 arcs[n].prev_in = -2;
268 first_node = first_free_node = first_free_arc = -1;
272 void changeTarget(Arc e, Node n)
274 if(arcs[e.id].next_in != -1)
275 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
276 if(arcs[e.id].prev_in != -1)
277 arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
278 else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
279 if (nodes[n.id].first_in != -1) {
280 arcs[nodes[n.id].first_in].prev_in = e.id;
282 arcs[e.id].target = n.id;
283 arcs[e.id].prev_in = -1;
284 arcs[e.id].next_in = nodes[n.id].first_in;
285 nodes[n.id].first_in = e.id;
287 void changeSource(Arc e, Node n)
289 if(arcs[e.id].next_out != -1)
290 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
291 if(arcs[e.id].prev_out != -1)
292 arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
293 else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
294 if (nodes[n.id].first_out != -1) {
295 arcs[nodes[n.id].first_out].prev_out = e.id;
297 arcs[e.id].source = n.id;
298 arcs[e.id].prev_out = -1;
299 arcs[e.id].next_out = nodes[n.id].first_out;
300 nodes[n.id].first_out = e.id;
305 typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
307 /// \addtogroup graphs
310 ///A general directed graph structure.
312 ///\ref ListDigraph is a simple and fast <em>directed graph</em>
313 ///implementation based on static linked lists that are stored in
314 ///\c std::vector structures.
316 ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
317 ///also provides several useful additional functionalities.
318 ///Most of the member functions and nested classes are documented
319 ///only in the concept class.
321 ///An important extra feature of this digraph implementation is that
322 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
324 ///\sa concepts::Digraph
326 class ListDigraph : public ExtendedListDigraphBase {
328 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
330 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
332 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
333 ///\brief Assignment of ListDigraph to another one is \e not allowed.
334 ///Use copyDigraph() instead.
336 ///Assignment of ListDigraph to another one is \e not allowed.
337 ///Use copyDigraph() instead.
338 void operator=(const ListDigraph &) {}
341 typedef ExtendedListDigraphBase Parent;
349 ///Add a new node to the digraph.
351 ///Add a new node to the digraph.
352 ///\return the new node.
353 Node addNode() { return Parent::addNode(); }
355 ///Add a new arc to the digraph.
357 ///Add a new arc to the digraph with source node \c s
358 ///and target node \c t.
359 ///\return the new arc.
360 Arc addArc(const Node& s, const Node& t) {
361 return Parent::addArc(s, t);
364 /// Node validity check
366 /// This function gives back true if the given node is valid,
367 /// ie. it is a real node of the graph.
369 /// \warning A Node pointing to a removed item
370 /// could become valid again later if new nodes are
371 /// added to the graph.
372 bool valid(Node n) const { return Parent::valid(n); }
374 /// Arc validity check
376 /// This function gives back true if the given arc is valid,
377 /// ie. it is a real arc of the graph.
379 /// \warning An Arc pointing to a removed item
380 /// could become valid again later if new nodes are
381 /// added to the graph.
382 bool valid(Arc a) const { return Parent::valid(a); }
384 /// Change the target of \c e to \c n
386 /// Change the target of \c e to \c n
388 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
389 ///the changed arc remain valid. However <tt>InArcIt</tt>s are
392 ///\warning This functionality cannot be used together with the Snapshot
394 void changeTarget(Arc e, Node n) {
395 Parent::changeTarget(e,n);
397 /// Change the source of \c e to \c n
399 /// Change the source of \c e to \c n
401 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
402 ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
405 ///\warning This functionality cannot be used together with the Snapshot
407 void changeSource(Arc e, Node n) {
408 Parent::changeSource(e,n);
411 /// Invert the direction of an arc.
413 ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
414 ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
417 ///\warning This functionality cannot be used together with the Snapshot
419 void reverseArc(Arc e) {
421 changeTarget(e,source(e));
425 /// Reserve memory for nodes.
427 /// Using this function it is possible to avoid the superfluous memory
428 /// allocation: if you know that the digraph you want to build will
429 /// be very large (e.g. it will contain millions of nodes and/or arcs)
430 /// then it is worth reserving space for this amount before starting
431 /// to build the digraph.
433 void reserveNode(int n) { nodes.reserve(n); };
435 /// Reserve memory for arcs.
437 /// Using this function it is possible to avoid the superfluous memory
438 /// allocation: if you know that the digraph you want to build will
439 /// be very large (e.g. it will contain millions of nodes and/or arcs)
440 /// then it is worth reserving space for this amount before starting
441 /// to build the digraph.
443 void reserveArc(int m) { arcs.reserve(m); };
445 ///Contract two nodes.
447 ///This function contracts two nodes.
448 ///Node \p b will be removed but instead of deleting
449 ///incident arcs, they will be joined to \p a.
450 ///The last parameter \p r controls whether to remove loops. \c true
451 ///means that loops will be removed.
453 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
454 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
455 ///may be invalidated.
457 ///\warning This functionality cannot be used together with the Snapshot
459 void contract(Node a, Node b, bool r = true)
461 for(OutArcIt e(*this,b);e!=INVALID;) {
464 if(r && target(e)==a) erase(e);
465 else changeSource(e,a);
468 for(InArcIt e(*this,b);e!=INVALID;) {
471 if(r && source(e)==a) erase(e);
472 else changeTarget(e,a);
480 ///This function splits a node. First a new node is added to the digraph,
481 ///then the source of each outgoing arc of \c n is moved to this new node.
482 ///If \c connect is \c true (this is the default value), then a new arc
483 ///from \c n to the newly created node is also added.
484 ///\return The newly created node.
486 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
487 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
490 ///\warning This functionality cannot be used together with the
493 ///\todo It could be implemented in a bit faster way.
494 Node split(Node n, bool connect = true) {
496 for(OutArcIt e(*this,n);e!=INVALID;) {
502 if (connect) addArc(n,b);
508 ///This function splits an arc. First a new node \c b is added to
509 ///the digraph, then the original arc is re-targeted to \c
510 ///b. Finally an arc from \c b to the original target is added.
512 ///\return The newly created node.
514 ///\warning This functionality cannot be used together with the
523 /// \brief Class to make a snapshot of the digraph and restore
526 /// Class to make a snapshot of the digraph and restore it later.
528 /// The newly added nodes and arcs can be removed using the
529 /// restore() function.
531 /// \warning Arc and node deletions and other modifications (e.g.
532 /// contracting, splitting, reversing arcs or nodes) cannot be
533 /// restored. These events invalidate the snapshot.
537 typedef Parent::NodeNotifier NodeNotifier;
539 class NodeObserverProxy : public NodeNotifier::ObserverBase {
542 NodeObserverProxy(Snapshot& _snapshot)
543 : snapshot(_snapshot) {}
545 using NodeNotifier::ObserverBase::attach;
546 using NodeNotifier::ObserverBase::detach;
547 using NodeNotifier::ObserverBase::attached;
551 virtual void add(const Node& node) {
552 snapshot.addNode(node);
554 virtual void add(const std::vector<Node>& nodes) {
555 for (int i = nodes.size() - 1; i >= 0; ++i) {
556 snapshot.addNode(nodes[i]);
559 virtual void erase(const Node& node) {
560 snapshot.eraseNode(node);
562 virtual void erase(const std::vector<Node>& nodes) {
563 for (int i = 0; i < int(nodes.size()); ++i) {
564 snapshot.eraseNode(nodes[i]);
567 virtual void build() {
569 std::vector<Node> nodes;
570 for (notifier()->first(node); node != INVALID;
571 notifier()->next(node)) {
572 nodes.push_back(node);
574 for (int i = nodes.size() - 1; i >= 0; --i) {
575 snapshot.addNode(nodes[i]);
578 virtual void clear() {
580 for (notifier()->first(node); node != INVALID;
581 notifier()->next(node)) {
582 snapshot.eraseNode(node);
589 class ArcObserverProxy : public ArcNotifier::ObserverBase {
592 ArcObserverProxy(Snapshot& _snapshot)
593 : snapshot(_snapshot) {}
595 using ArcNotifier::ObserverBase::attach;
596 using ArcNotifier::ObserverBase::detach;
597 using ArcNotifier::ObserverBase::attached;
601 virtual void add(const Arc& arc) {
602 snapshot.addArc(arc);
604 virtual void add(const std::vector<Arc>& arcs) {
605 for (int i = arcs.size() - 1; i >= 0; ++i) {
606 snapshot.addArc(arcs[i]);
609 virtual void erase(const Arc& arc) {
610 snapshot.eraseArc(arc);
612 virtual void erase(const std::vector<Arc>& arcs) {
613 for (int i = 0; i < int(arcs.size()); ++i) {
614 snapshot.eraseArc(arcs[i]);
617 virtual void build() {
619 std::vector<Arc> arcs;
620 for (notifier()->first(arc); arc != INVALID;
621 notifier()->next(arc)) {
624 for (int i = arcs.size() - 1; i >= 0; --i) {
625 snapshot.addArc(arcs[i]);
628 virtual void clear() {
630 for (notifier()->first(arc); arc != INVALID;
631 notifier()->next(arc)) {
632 snapshot.eraseArc(arc);
639 ListDigraph *digraph;
641 NodeObserverProxy node_observer_proxy;
642 ArcObserverProxy arc_observer_proxy;
644 std::list<Node> added_nodes;
645 std::list<Arc> added_arcs;
648 void addNode(const Node& node) {
649 added_nodes.push_front(node);
651 void eraseNode(const Node& node) {
652 std::list<Node>::iterator it =
653 std::find(added_nodes.begin(), added_nodes.end(), node);
654 if (it == added_nodes.end()) {
656 arc_observer_proxy.detach();
657 throw NodeNotifier::ImmediateDetach();
659 added_nodes.erase(it);
663 void addArc(const Arc& arc) {
664 added_arcs.push_front(arc);
666 void eraseArc(const Arc& arc) {
667 std::list<Arc>::iterator it =
668 std::find(added_arcs.begin(), added_arcs.end(), arc);
669 if (it == added_arcs.end()) {
671 node_observer_proxy.detach();
672 throw ArcNotifier::ImmediateDetach();
674 added_arcs.erase(it);
678 void attach(ListDigraph &_digraph) {
680 node_observer_proxy.attach(digraph->notifier(Node()));
681 arc_observer_proxy.attach(digraph->notifier(Arc()));
685 node_observer_proxy.detach();
686 arc_observer_proxy.detach();
689 bool attached() const {
690 return node_observer_proxy.attached();
700 /// \brief Default constructor.
702 /// Default constructor.
703 /// To actually make a snapshot you must call save().
705 : digraph(0), node_observer_proxy(*this),
706 arc_observer_proxy(*this) {}
708 /// \brief Constructor that immediately makes a snapshot.
710 /// This constructor immediately makes a snapshot of the digraph.
711 /// \param _digraph The digraph we make a snapshot of.
712 Snapshot(ListDigraph &_digraph)
713 : node_observer_proxy(*this),
714 arc_observer_proxy(*this) {
718 /// \brief Make a snapshot.
720 /// Make a snapshot of the digraph.
722 /// This function can be called more than once. In case of a repeated
723 /// call, the previous snapshot gets lost.
724 /// \param _digraph The digraph we make the snapshot of.
725 void save(ListDigraph &_digraph) {
733 /// \brief Undo the changes until the last snapshot.
735 /// Undo the changes until the last snapshot created by save().
738 for(std::list<Arc>::iterator it = added_arcs.begin();
739 it != added_arcs.end(); ++it) {
742 for(std::list<Node>::iterator it = added_nodes.begin();
743 it != added_nodes.end(); ++it) {
749 /// \brief Gives back true when the snapshot is valid.
751 /// Gives back true when the snapshot is valid.
761 class ListGraphBase {
772 int prev_out, next_out;
775 std::vector<NodeT> nodes;
781 std::vector<ArcT> arcs;
787 typedef ListGraphBase Digraph;
794 friend class ListGraphBase;
798 explicit Node(int pid) { id = pid;}
802 Node (Invalid) { id = -1; }
803 bool operator==(const Node& node) const {return id == node.id;}
804 bool operator!=(const Node& node) const {return id != node.id;}
805 bool operator<(const Node& node) const {return id < node.id;}
809 friend class ListGraphBase;
813 explicit Edge(int pid) { id = pid;}
817 Edge (Invalid) { id = -1; }
818 bool operator==(const Edge& edge) const {return id == edge.id;}
819 bool operator!=(const Edge& edge) const {return id != edge.id;}
820 bool operator<(const Edge& edge) const {return id < edge.id;}
824 friend class ListGraphBase;
828 explicit Arc(int pid) { id = pid;}
831 operator Edge() const { return edgeFromId(id / 2); }
834 Arc (Invalid) { id = -1; }
835 bool operator==(const Arc& arc) const {return id == arc.id;}
836 bool operator!=(const Arc& arc) const {return id != arc.id;}
837 bool operator<(const Arc& arc) const {return id < arc.id;}
843 : nodes(), first_node(-1),
844 first_free_node(-1), arcs(), first_free_arc(-1) {}
847 int maxNodeId() const { return nodes.size()-1; }
848 int maxEdgeId() const { return arcs.size() / 2 - 1; }
849 int maxArcId() const { return arcs.size()-1; }
851 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
852 Node target(Arc e) const { return Node(arcs[e.id].target); }
854 Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
855 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
857 static bool direction(Arc e) {
858 return (e.id & 1) == 1;
861 static Arc direct(Edge e, bool d) {
862 return Arc(e.id * 2 + (d ? 1 : 0));
865 void first(Node& node) const {
866 node.id = first_node;
869 void next(Node& node) const {
870 node.id = nodes[node.id].next;
873 void first(Arc& e) const {
875 while (n != -1 && nodes[n].first_out == -1) {
878 e.id = (n == -1) ? -1 : nodes[n].first_out;
881 void next(Arc& e) const {
882 if (arcs[e.id].next_out != -1) {
883 e.id = arcs[e.id].next_out;
885 int n = nodes[arcs[e.id ^ 1].target].next;
886 while(n != -1 && nodes[n].first_out == -1) {
889 e.id = (n == -1) ? -1 : nodes[n].first_out;
893 void first(Edge& e) const {
896 e.id = nodes[n].first_out;
897 while ((e.id & 1) != 1) {
898 e.id = arcs[e.id].next_out;
909 void next(Edge& e) const {
910 int n = arcs[e.id * 2].target;
911 e.id = arcs[(e.id * 2) | 1].next_out;
912 while ((e.id & 1) != 1) {
913 e.id = arcs[e.id].next_out;
921 e.id = nodes[n].first_out;
922 while ((e.id & 1) != 1) {
923 e.id = arcs[e.id].next_out;
934 void firstOut(Arc &e, const Node& v) const {
935 e.id = nodes[v.id].first_out;
937 void nextOut(Arc &e) const {
938 e.id = arcs[e.id].next_out;
941 void firstIn(Arc &e, const Node& v) const {
942 e.id = ((nodes[v.id].first_out) ^ 1);
943 if (e.id == -2) e.id = -1;
945 void nextIn(Arc &e) const {
946 e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
947 if (e.id == -2) e.id = -1;
950 void firstInc(Edge &e, bool& d, const Node& v) const {
951 int a = nodes[v.id].first_out;
960 void nextInc(Edge &e, bool& d) const {
961 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
971 static int id(Node v) { return v.id; }
972 static int id(Arc e) { return e.id; }
973 static int id(Edge e) { return e.id; }
975 static Node nodeFromId(int id) { return Node(id);}
976 static Arc arcFromId(int id) { return Arc(id);}
977 static Edge edgeFromId(int id) { return Edge(id);}
979 bool valid(Node n) const {
980 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
981 nodes[n.id].prev != -2;
984 bool valid(Arc a) const {
985 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
986 arcs[a.id].prev_out != -2;
989 bool valid(Edge e) const {
990 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
991 arcs[2 * e.id].prev_out != -2;
997 if(first_free_node==-1) {
999 nodes.push_back(NodeT());
1001 n = first_free_node;
1002 first_free_node = nodes[n].next;
1005 nodes[n].next = first_node;
1006 if (first_node != -1) nodes[first_node].prev = n;
1010 nodes[n].first_out = -1;
1015 Edge addEdge(Node u, Node v) {
1018 if (first_free_arc == -1) {
1020 arcs.push_back(ArcT());
1021 arcs.push_back(ArcT());
1024 first_free_arc = arcs[n].next_out;
1027 arcs[n].target = u.id;
1028 arcs[n | 1].target = v.id;
1030 arcs[n].next_out = nodes[v.id].first_out;
1031 if (nodes[v.id].first_out != -1) {
1032 arcs[nodes[v.id].first_out].prev_out = n;
1034 arcs[n].prev_out = -1;
1035 nodes[v.id].first_out = n;
1037 arcs[n | 1].next_out = nodes[u.id].first_out;
1038 if (nodes[u.id].first_out != -1) {
1039 arcs[nodes[u.id].first_out].prev_out = (n | 1);
1041 arcs[n | 1].prev_out = -1;
1042 nodes[u.id].first_out = (n | 1);
1047 void erase(const Node& node) {
1050 if(nodes[n].next != -1) {
1051 nodes[nodes[n].next].prev = nodes[n].prev;
1054 if(nodes[n].prev != -1) {
1055 nodes[nodes[n].prev].next = nodes[n].next;
1057 first_node = nodes[n].next;
1060 nodes[n].next = first_free_node;
1061 first_free_node = n;
1065 void erase(const Edge& edge) {
1066 int n = edge.id * 2;
1068 if (arcs[n].next_out != -1) {
1069 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1072 if (arcs[n].prev_out != -1) {
1073 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1075 nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1078 if (arcs[n | 1].next_out != -1) {
1079 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1082 if (arcs[n | 1].prev_out != -1) {
1083 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1085 nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1088 arcs[n].next_out = first_free_arc;
1090 arcs[n].prev_out = -2;
1091 arcs[n | 1].prev_out = -2;
1098 first_node = first_free_node = first_free_arc = -1;
1103 void changeTarget(Edge e, Node n) {
1104 if(arcs[2 * e.id].next_out != -1) {
1105 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1107 if(arcs[2 * e.id].prev_out != -1) {
1108 arcs[arcs[2 * e.id].prev_out].next_out =
1109 arcs[2 * e.id].next_out;
1111 nodes[arcs[(2 * e.id) | 1].target].first_out =
1112 arcs[2 * e.id].next_out;
1115 if (nodes[n.id].first_out != -1) {
1116 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1118 arcs[(2 * e.id) | 1].target = n.id;
1119 arcs[2 * e.id].prev_out = -1;
1120 arcs[2 * e.id].next_out = nodes[n.id].first_out;
1121 nodes[n.id].first_out = 2 * e.id;
1124 void changeSource(Edge e, Node n) {
1125 if(arcs[(2 * e.id) | 1].next_out != -1) {
1126 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1127 arcs[(2 * e.id) | 1].prev_out;
1129 if(arcs[(2 * e.id) | 1].prev_out != -1) {
1130 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1131 arcs[(2 * e.id) | 1].next_out;
1133 nodes[arcs[2 * e.id].target].first_out =
1134 arcs[(2 * e.id) | 1].next_out;
1137 if (nodes[n.id].first_out != -1) {
1138 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1140 arcs[2 * e.id].target = n.id;
1141 arcs[(2 * e.id) | 1].prev_out = -1;
1142 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1143 nodes[n.id].first_out = ((2 * e.id) | 1);
1148 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1151 /// \addtogroup graphs
1154 ///A general undirected graph structure.
1156 ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1157 ///implementation based on static linked lists that are stored in
1158 ///\c std::vector structures.
1160 ///It conforms to the \ref concepts::Graph "Graph concept" and it
1161 ///also provides several useful additional functionalities.
1162 ///Most of the member functions and nested classes are documented
1163 ///only in the concept class.
1165 ///An important extra feature of this graph implementation is that
1166 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1168 ///\sa concepts::Graph
1170 class ListGraph : public ExtendedListGraphBase {
1172 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1174 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1176 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
1177 ///\brief Assignment of ListGraph to another one is \e not allowed.
1178 ///Use copyGraph() instead.
1180 ///Assignment of ListGraph to another one is \e not allowed.
1181 ///Use copyGraph() instead.
1182 void operator=(const ListGraph &) {}
1190 typedef ExtendedListGraphBase Parent;
1192 typedef Parent::OutArcIt IncEdgeIt;
1194 /// \brief Add a new node to the graph.
1196 /// Add a new node to the graph.
1197 /// \return the new node.
1198 Node addNode() { return Parent::addNode(); }
1200 /// \brief Add a new edge to the graph.
1202 /// Add a new edge to the graph with source node \c s
1203 /// and target node \c t.
1204 /// \return the new edge.
1205 Edge addEdge(const Node& s, const Node& t) {
1206 return Parent::addEdge(s, t);
1208 /// Node validity check
1210 /// This function gives back true if the given node is valid,
1211 /// ie. it is a real node of the graph.
1213 /// \warning A Node pointing to a removed item
1214 /// could become valid again later if new nodes are
1215 /// added to the graph.
1216 bool valid(Node n) const { return Parent::valid(n); }
1217 /// Arc validity check
1219 /// This function gives back true if the given arc is valid,
1220 /// ie. it is a real arc of the graph.
1222 /// \warning An Arc pointing to a removed item
1223 /// could become valid again later if new edges are
1224 /// added to the graph.
1225 bool valid(Arc a) const { return Parent::valid(a); }
1226 /// Edge validity check
1228 /// This function gives back true if the given edge is valid,
1229 /// ie. it is a real arc of the graph.
1231 /// \warning A Edge pointing to a removed item
1232 /// could become valid again later if new edges are
1233 /// added to the graph.
1234 bool valid(Edge e) const { return Parent::valid(e); }
1235 /// \brief Change the source of \c e to \c n
1237 /// This function changes the source of \c e to \c n.
1239 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1240 ///referencing the changed arc remain
1241 ///valid. However <tt>OutArcIt</tt>s are invalidated.
1243 ///\warning This functionality cannot be used together with the
1244 ///Snapshot feature.
1245 void changeSource(Edge e, Node n) {
1246 Parent::changeSource(e,n);
1248 /// \brief Change the target of \c e to \c n
1250 /// This function changes the target of \c e to \c n.
1252 /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1253 /// valid. However the other iterators may be invalidated.
1255 ///\warning This functionality cannot be used together with the
1256 ///Snapshot feature.
1257 void changeTarget(Edge e, Node n) {
1258 Parent::changeTarget(e,n);
1260 /// \brief Change the source of \c e to \c n
1262 /// This function changes the source of \c e to \c n.
1263 /// It also changes the proper node of the represented edge.
1265 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1266 ///referencing the changed arc remain
1267 ///valid. However <tt>OutArcIt</tt>s are invalidated.
1269 ///\warning This functionality cannot be used together with the
1270 ///Snapshot feature.
1271 void changeSource(Arc e, Node n) {
1272 if (Parent::direction(e)) {
1273 Parent::changeSource(e,n);
1275 Parent::changeTarget(e,n);
1278 /// \brief Change the target of \c e to \c n
1280 /// This function changes the target of \c e to \c n.
1281 /// It also changes the proper node of the represented edge.
1283 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
1284 ///referencing the changed arc remain
1285 ///valid. However <tt>InArcIt</tt>s are invalidated.
1287 ///\warning This functionality cannot be used together with the
1288 ///Snapshot feature.
1289 void changeTarget(Arc e, Node n) {
1290 if (Parent::direction(e)) {
1291 Parent::changeTarget(e,n);
1293 Parent::changeSource(e,n);
1296 /// \brief Contract two nodes.
1298 /// This function contracts two nodes.
1299 /// Node \p b will be removed but instead of deleting
1300 /// its neighboring arcs, they will be joined to \p a.
1301 /// The last parameter \p r controls whether to remove loops. \c true
1302 /// means that loops will be removed.
1304 /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1307 ///\warning This functionality cannot be used together with the
1308 ///Snapshot feature.
1309 void contract(Node a, Node b, bool r = true) {
1310 for(IncEdgeIt e(*this, b); e!=INVALID;) {
1311 IncEdgeIt f = e; ++f;
1312 if (r && runningNode(e) == a) {
1314 } else if (source(e) == b) {
1325 /// \brief Class to make a snapshot of the graph and restore
1328 /// Class to make a snapshot of the graph and restore it later.
1330 /// The newly added nodes and edges can be removed
1331 /// using the restore() function.
1333 /// \warning Edge and node deletions and other modifications
1334 /// (e.g. changing nodes of edges, contracting nodes) cannot be
1335 /// restored. These events invalidate the snapshot.
1339 typedef Parent::NodeNotifier NodeNotifier;
1341 class NodeObserverProxy : public NodeNotifier::ObserverBase {
1344 NodeObserverProxy(Snapshot& _snapshot)
1345 : snapshot(_snapshot) {}
1347 using NodeNotifier::ObserverBase::attach;
1348 using NodeNotifier::ObserverBase::detach;
1349 using NodeNotifier::ObserverBase::attached;
1353 virtual void add(const Node& node) {
1354 snapshot.addNode(node);
1356 virtual void add(const std::vector<Node>& nodes) {
1357 for (int i = nodes.size() - 1; i >= 0; ++i) {
1358 snapshot.addNode(nodes[i]);
1361 virtual void erase(const Node& node) {
1362 snapshot.eraseNode(node);
1364 virtual void erase(const std::vector<Node>& nodes) {
1365 for (int i = 0; i < int(nodes.size()); ++i) {
1366 snapshot.eraseNode(nodes[i]);
1369 virtual void build() {
1371 std::vector<Node> nodes;
1372 for (notifier()->first(node); node != INVALID;
1373 notifier()->next(node)) {
1374 nodes.push_back(node);
1376 for (int i = nodes.size() - 1; i >= 0; --i) {
1377 snapshot.addNode(nodes[i]);
1380 virtual void clear() {
1382 for (notifier()->first(node); node != INVALID;
1383 notifier()->next(node)) {
1384 snapshot.eraseNode(node);
1391 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1394 EdgeObserverProxy(Snapshot& _snapshot)
1395 : snapshot(_snapshot) {}
1397 using EdgeNotifier::ObserverBase::attach;
1398 using EdgeNotifier::ObserverBase::detach;
1399 using EdgeNotifier::ObserverBase::attached;
1403 virtual void add(const Edge& edge) {
1404 snapshot.addEdge(edge);
1406 virtual void add(const std::vector<Edge>& edges) {
1407 for (int i = edges.size() - 1; i >= 0; ++i) {
1408 snapshot.addEdge(edges[i]);
1411 virtual void erase(const Edge& edge) {
1412 snapshot.eraseEdge(edge);
1414 virtual void erase(const std::vector<Edge>& edges) {
1415 for (int i = 0; i < int(edges.size()); ++i) {
1416 snapshot.eraseEdge(edges[i]);
1419 virtual void build() {
1421 std::vector<Edge> edges;
1422 for (notifier()->first(edge); edge != INVALID;
1423 notifier()->next(edge)) {
1424 edges.push_back(edge);
1426 for (int i = edges.size() - 1; i >= 0; --i) {
1427 snapshot.addEdge(edges[i]);
1430 virtual void clear() {
1432 for (notifier()->first(edge); edge != INVALID;
1433 notifier()->next(edge)) {
1434 snapshot.eraseEdge(edge);
1443 NodeObserverProxy node_observer_proxy;
1444 EdgeObserverProxy edge_observer_proxy;
1446 std::list<Node> added_nodes;
1447 std::list<Edge> added_edges;
1450 void addNode(const Node& node) {
1451 added_nodes.push_front(node);
1453 void eraseNode(const Node& node) {
1454 std::list<Node>::iterator it =
1455 std::find(added_nodes.begin(), added_nodes.end(), node);
1456 if (it == added_nodes.end()) {
1458 edge_observer_proxy.detach();
1459 throw NodeNotifier::ImmediateDetach();
1461 added_nodes.erase(it);
1465 void addEdge(const Edge& edge) {
1466 added_edges.push_front(edge);
1468 void eraseEdge(const Edge& edge) {
1469 std::list<Edge>::iterator it =
1470 std::find(added_edges.begin(), added_edges.end(), edge);
1471 if (it == added_edges.end()) {
1473 node_observer_proxy.detach();
1474 throw EdgeNotifier::ImmediateDetach();
1476 added_edges.erase(it);
1480 void attach(ListGraph &_graph) {
1482 node_observer_proxy.attach(graph->notifier(Node()));
1483 edge_observer_proxy.attach(graph->notifier(Edge()));
1487 node_observer_proxy.detach();
1488 edge_observer_proxy.detach();
1491 bool attached() const {
1492 return node_observer_proxy.attached();
1496 added_nodes.clear();
1497 added_edges.clear();
1502 /// \brief Default constructor.
1504 /// Default constructor.
1505 /// To actually make a snapshot you must call save().
1507 : graph(0), node_observer_proxy(*this),
1508 edge_observer_proxy(*this) {}
1510 /// \brief Constructor that immediately makes a snapshot.
1512 /// This constructor immediately makes a snapshot of the graph.
1513 /// \param _graph The graph we make a snapshot of.
1514 Snapshot(ListGraph &_graph)
1515 : node_observer_proxy(*this),
1516 edge_observer_proxy(*this) {
1520 /// \brief Make a snapshot.
1522 /// Make a snapshot of the graph.
1524 /// This function can be called more than once. In case of a repeated
1525 /// call, the previous snapshot gets lost.
1526 /// \param _graph The graph we make the snapshot of.
1527 void save(ListGraph &_graph) {
1535 /// \brief Undo the changes until the last snapshot.
1537 /// Undo the changes until the last snapshot created by save().
1540 for(std::list<Edge>::iterator it = added_edges.begin();
1541 it != added_edges.end(); ++it) {
1544 for(std::list<Node>::iterator it = added_nodes.begin();
1545 it != added_nodes.end(); ++it) {
1551 /// \brief Gives back true when the snapshot is valid.
1553 /// Gives back true when the snapshot is valid.
1554 bool valid() const {