1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2009
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/core.h>
27 #include <lemon/error.h>
28 #include <lemon/bits/graph_extender.h>
35 class ListDigraphBase {
39 int first_in, first_out;
45 int prev_in, prev_out;
46 int next_in, next_out;
49 std::vector<NodeT> nodes;
55 std::vector<ArcT> arcs;
61 typedef ListDigraphBase Digraph;
64 friend class ListDigraphBase;
68 explicit Node(int pid) { id = pid;}
72 Node (Invalid) { id = -1; }
73 bool operator==(const Node& node) const {return id == node.id;}
74 bool operator!=(const Node& node) const {return id != node.id;}
75 bool operator<(const Node& node) const {return id < node.id;}
79 friend class ListDigraphBase;
83 explicit Arc(int pid) { id = pid;}
87 Arc (Invalid) { id = -1; }
88 bool operator==(const Arc& arc) const {return id == arc.id;}
89 bool operator!=(const Arc& arc) const {return id != arc.id;}
90 bool operator<(const Arc& arc) const {return id < arc.id;}
96 : nodes(), first_node(-1),
97 first_free_node(-1), arcs(), first_free_arc(-1) {}
100 int maxNodeId() const { return nodes.size()-1; }
101 int maxArcId() const { return arcs.size()-1; }
103 Node source(Arc e) const { return Node(arcs[e.id].source); }
104 Node target(Arc e) const { return Node(arcs[e.id].target); }
107 void first(Node& node) const {
108 node.id = first_node;
111 void next(Node& node) const {
112 node.id = nodes[node.id].next;
116 void first(Arc& arc) const {
119 n!=-1 && nodes[n].first_in == -1;
120 n = nodes[n].next) {}
121 arc.id = (n == -1) ? -1 : nodes[n].first_in;
124 void next(Arc& arc) const {
125 if (arcs[arc.id].next_in != -1) {
126 arc.id = arcs[arc.id].next_in;
129 for(n = nodes[arcs[arc.id].target].next;
130 n!=-1 && nodes[n].first_in == -1;
131 n = nodes[n].next) {}
132 arc.id = (n == -1) ? -1 : nodes[n].first_in;
136 void firstOut(Arc &e, const Node& v) const {
137 e.id = nodes[v.id].first_out;
139 void nextOut(Arc &e) const {
140 e.id=arcs[e.id].next_out;
143 void firstIn(Arc &e, const Node& v) const {
144 e.id = nodes[v.id].first_in;
146 void nextIn(Arc &e) const {
147 e.id=arcs[e.id].next_in;
151 static int id(Node v) { return v.id; }
152 static int id(Arc e) { return e.id; }
154 static Node nodeFromId(int id) { return Node(id);}
155 static Arc arcFromId(int id) { return Arc(id);}
157 bool valid(Node n) const {
158 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159 nodes[n.id].prev != -2;
162 bool valid(Arc a) const {
163 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164 arcs[a.id].prev_in != -2;
170 if(first_free_node==-1) {
172 nodes.push_back(NodeT());
175 first_free_node = nodes[n].next;
178 nodes[n].next = first_node;
179 if(first_node != -1) nodes[first_node].prev = n;
183 nodes[n].first_in = nodes[n].first_out = -1;
188 Arc addArc(Node u, Node v) {
191 if (first_free_arc == -1) {
193 arcs.push_back(ArcT());
196 first_free_arc = arcs[n].next_in;
199 arcs[n].source = u.id;
200 arcs[n].target = v.id;
202 arcs[n].next_out = nodes[u.id].first_out;
203 if(nodes[u.id].first_out != -1) {
204 arcs[nodes[u.id].first_out].prev_out = n;
207 arcs[n].next_in = nodes[v.id].first_in;
208 if(nodes[v.id].first_in != -1) {
209 arcs[nodes[v.id].first_in].prev_in = n;
212 arcs[n].prev_in = arcs[n].prev_out = -1;
214 nodes[u.id].first_out = nodes[v.id].first_in = n;
219 void erase(const Node& node) {
222 if(nodes[n].next != -1) {
223 nodes[nodes[n].next].prev = nodes[n].prev;
226 if(nodes[n].prev != -1) {
227 nodes[nodes[n].prev].next = nodes[n].next;
229 first_node = nodes[n].next;
232 nodes[n].next = first_free_node;
238 void erase(const Arc& arc) {
241 if(arcs[n].next_in!=-1) {
242 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
245 if(arcs[n].prev_in!=-1) {
246 arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
248 nodes[arcs[n].target].first_in = arcs[n].next_in;
252 if(arcs[n].next_out!=-1) {
253 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
256 if(arcs[n].prev_out!=-1) {
257 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
259 nodes[arcs[n].source].first_out = arcs[n].next_out;
262 arcs[n].next_in = first_free_arc;
264 arcs[n].prev_in = -2;
270 first_node = first_free_node = first_free_arc = -1;
274 void changeTarget(Arc e, Node n)
276 if(arcs[e.id].next_in != -1)
277 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
278 if(arcs[e.id].prev_in != -1)
279 arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
280 else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
281 if (nodes[n.id].first_in != -1) {
282 arcs[nodes[n.id].first_in].prev_in = e.id;
284 arcs[e.id].target = n.id;
285 arcs[e.id].prev_in = -1;
286 arcs[e.id].next_in = nodes[n.id].first_in;
287 nodes[n.id].first_in = e.id;
289 void changeSource(Arc e, Node n)
291 if(arcs[e.id].next_out != -1)
292 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
293 if(arcs[e.id].prev_out != -1)
294 arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
295 else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
296 if (nodes[n.id].first_out != -1) {
297 arcs[nodes[n.id].first_out].prev_out = e.id;
299 arcs[e.id].source = n.id;
300 arcs[e.id].prev_out = -1;
301 arcs[e.id].next_out = nodes[n.id].first_out;
302 nodes[n.id].first_out = e.id;
307 typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
309 /// \addtogroup graphs
312 ///A general directed graph structure.
314 ///\ref ListDigraph is a simple and fast <em>directed graph</em>
315 ///implementation based on static linked lists that are stored in
316 ///\c std::vector structures.
318 ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
319 ///also provides several useful additional functionalities.
320 ///Most of the member functions and nested classes are documented
321 ///only in the concept class.
323 ///\sa concepts::Digraph
325 class ListDigraph : public ExtendedListDigraphBase {
326 typedef ExtendedListDigraphBase Parent;
329 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
331 ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
333 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
334 ///\brief Assignment of ListDigraph to another one is \e not allowed.
335 ///Use copyDigraph() instead.
337 ///Assignment of ListDigraph to another one is \e not allowed.
338 ///Use copyDigraph() instead.
339 void operator=(const ListDigraph &) {}
348 ///Add a new node to the digraph.
350 ///Add a new node to the digraph.
351 ///\return The new node.
352 Node addNode() { return Parent::addNode(); }
354 ///Add a new arc to the digraph.
356 ///Add a new arc to the digraph with source node \c s
357 ///and target node \c t.
358 ///\return The new arc.
359 Arc addArc(const Node& s, const Node& t) {
360 return Parent::addArc(s, t);
363 ///\brief Erase a node from the digraph.
365 ///Erase a node from the digraph.
367 void erase(const Node& n) { Parent::erase(n); }
369 ///\brief Erase an arc from the digraph.
371 ///Erase an arc from the digraph.
373 void erase(const Arc& a) { Parent::erase(a); }
375 /// Node validity check
377 /// This function gives back true if the given node is valid,
378 /// ie. it is a real node of the graph.
380 /// \warning A Node pointing to a removed item
381 /// could become valid again later if new nodes are
382 /// added to the graph.
383 bool valid(Node n) const { return Parent::valid(n); }
385 /// Arc validity check
387 /// This function gives back true if the given arc is valid,
388 /// ie. it is a real arc of the graph.
390 /// \warning An Arc pointing to a removed item
391 /// could become valid again later if new nodes are
392 /// added to the graph.
393 bool valid(Arc a) const { return Parent::valid(a); }
395 /// Change the target of \c a to \c n
397 /// Change the target of \c a to \c n
399 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
400 ///the changed arc remain valid. However <tt>InArcIt</tt>s are
403 ///\warning This functionality cannot be used together with the Snapshot
405 void changeTarget(Arc a, Node n) {
406 Parent::changeTarget(a,n);
408 /// Change the source of \c a to \c n
410 /// Change the source of \c a to \c n
412 ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
413 ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
416 ///\warning This functionality cannot be used together with the Snapshot
418 void changeSource(Arc a, Node n) {
419 Parent::changeSource(a,n);
422 /// Invert the direction of an arc.
424 ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
425 ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
428 ///\warning This functionality cannot be used together with the Snapshot
430 void reverseArc(Arc e) {
432 changeTarget(e,source(e));
436 /// Reserve memory for nodes.
438 /// Using this function it is possible to avoid the superfluous memory
439 /// allocation: if you know that the digraph you want to build will
440 /// be very large (e.g. it will contain millions of nodes and/or arcs)
441 /// then it is worth reserving space for this amount before starting
442 /// to build the digraph.
444 void reserveNode(int n) { nodes.reserve(n); };
446 /// Reserve memory for arcs.
448 /// Using this function it is possible to avoid the superfluous memory
449 /// allocation: if you know that the digraph you want to build will
450 /// be very large (e.g. it will contain millions of nodes and/or arcs)
451 /// then it is worth reserving space for this amount before starting
452 /// to build the digraph.
454 void reserveArc(int m) { arcs.reserve(m); };
456 ///Contract two nodes.
458 ///This function contracts two nodes.
459 ///Node \p b will be removed but instead of deleting
460 ///incident arcs, they will be joined to \p a.
461 ///The last parameter \p r controls whether to remove loops. \c true
462 ///means that loops will be removed.
464 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
465 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
466 ///may be invalidated.
468 ///\warning This functionality cannot be used together with the Snapshot
470 void contract(Node a, Node b, bool r = true)
472 for(OutArcIt e(*this,b);e!=INVALID;) {
475 if(r && target(e)==a) erase(e);
476 else changeSource(e,a);
479 for(InArcIt e(*this,b);e!=INVALID;) {
482 if(r && source(e)==a) erase(e);
483 else changeTarget(e,a);
491 ///This function splits a node. First a new node is added to the digraph,
492 ///then the source of each outgoing arc of \c n is moved to this new node.
493 ///If \c connect is \c true (this is the default value), then a new arc
494 ///from \c n to the newly created node is also added.
495 ///\return The newly created node.
497 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
498 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
501 ///\warning This functionality cannot be used in conjunction with the
503 Node split(Node n, bool connect = true) {
505 for(OutArcIt e(*this,n);e!=INVALID;) {
511 if (connect) addArc(n,b);
517 ///This function splits an arc. First a new node \c b is added to
518 ///the digraph, then the original arc is re-targeted to \c
519 ///b. Finally an arc from \c b to the original target is added.
521 ///\return The newly created node.
523 ///\warning This functionality cannot be used together with the
532 /// \brief Class to make a snapshot of the digraph and restore
535 /// Class to make a snapshot of the digraph and restore it later.
537 /// The newly added nodes and arcs can be removed using the
538 /// restore() function.
540 /// \warning Arc and node deletions and other modifications (e.g.
541 /// contracting, splitting, reversing arcs or nodes) cannot be
542 /// restored. These events invalidate the snapshot.
546 typedef Parent::NodeNotifier NodeNotifier;
548 class NodeObserverProxy : public NodeNotifier::ObserverBase {
551 NodeObserverProxy(Snapshot& _snapshot)
552 : snapshot(_snapshot) {}
554 using NodeNotifier::ObserverBase::attach;
555 using NodeNotifier::ObserverBase::detach;
556 using NodeNotifier::ObserverBase::attached;
560 virtual void add(const Node& node) {
561 snapshot.addNode(node);
563 virtual void add(const std::vector<Node>& nodes) {
564 for (int i = nodes.size() - 1; i >= 0; ++i) {
565 snapshot.addNode(nodes[i]);
568 virtual void erase(const Node& node) {
569 snapshot.eraseNode(node);
571 virtual void erase(const std::vector<Node>& nodes) {
572 for (int i = 0; i < int(nodes.size()); ++i) {
573 snapshot.eraseNode(nodes[i]);
576 virtual void build() {
578 std::vector<Node> nodes;
579 for (notifier()->first(node); node != INVALID;
580 notifier()->next(node)) {
581 nodes.push_back(node);
583 for (int i = nodes.size() - 1; i >= 0; --i) {
584 snapshot.addNode(nodes[i]);
587 virtual void clear() {
589 for (notifier()->first(node); node != INVALID;
590 notifier()->next(node)) {
591 snapshot.eraseNode(node);
598 class ArcObserverProxy : public ArcNotifier::ObserverBase {
601 ArcObserverProxy(Snapshot& _snapshot)
602 : snapshot(_snapshot) {}
604 using ArcNotifier::ObserverBase::attach;
605 using ArcNotifier::ObserverBase::detach;
606 using ArcNotifier::ObserverBase::attached;
610 virtual void add(const Arc& arc) {
611 snapshot.addArc(arc);
613 virtual void add(const std::vector<Arc>& arcs) {
614 for (int i = arcs.size() - 1; i >= 0; ++i) {
615 snapshot.addArc(arcs[i]);
618 virtual void erase(const Arc& arc) {
619 snapshot.eraseArc(arc);
621 virtual void erase(const std::vector<Arc>& arcs) {
622 for (int i = 0; i < int(arcs.size()); ++i) {
623 snapshot.eraseArc(arcs[i]);
626 virtual void build() {
628 std::vector<Arc> arcs;
629 for (notifier()->first(arc); arc != INVALID;
630 notifier()->next(arc)) {
633 for (int i = arcs.size() - 1; i >= 0; --i) {
634 snapshot.addArc(arcs[i]);
637 virtual void clear() {
639 for (notifier()->first(arc); arc != INVALID;
640 notifier()->next(arc)) {
641 snapshot.eraseArc(arc);
648 ListDigraph *digraph;
650 NodeObserverProxy node_observer_proxy;
651 ArcObserverProxy arc_observer_proxy;
653 std::list<Node> added_nodes;
654 std::list<Arc> added_arcs;
657 void addNode(const Node& node) {
658 added_nodes.push_front(node);
660 void eraseNode(const Node& node) {
661 std::list<Node>::iterator it =
662 std::find(added_nodes.begin(), added_nodes.end(), node);
663 if (it == added_nodes.end()) {
665 arc_observer_proxy.detach();
666 throw NodeNotifier::ImmediateDetach();
668 added_nodes.erase(it);
672 void addArc(const Arc& arc) {
673 added_arcs.push_front(arc);
675 void eraseArc(const Arc& arc) {
676 std::list<Arc>::iterator it =
677 std::find(added_arcs.begin(), added_arcs.end(), arc);
678 if (it == added_arcs.end()) {
680 node_observer_proxy.detach();
681 throw ArcNotifier::ImmediateDetach();
683 added_arcs.erase(it);
687 void attach(ListDigraph &_digraph) {
689 node_observer_proxy.attach(digraph->notifier(Node()));
690 arc_observer_proxy.attach(digraph->notifier(Arc()));
694 node_observer_proxy.detach();
695 arc_observer_proxy.detach();
698 bool attached() const {
699 return node_observer_proxy.attached();
709 /// \brief Default constructor.
711 /// Default constructor.
712 /// To actually make a snapshot you must call save().
714 : digraph(0), node_observer_proxy(*this),
715 arc_observer_proxy(*this) {}
717 /// \brief Constructor that immediately makes a snapshot.
719 /// This constructor immediately makes a snapshot of the digraph.
720 /// \param _digraph The digraph we make a snapshot of.
721 Snapshot(ListDigraph &_digraph)
722 : node_observer_proxy(*this),
723 arc_observer_proxy(*this) {
727 /// \brief Make a snapshot.
729 /// Make a snapshot of the digraph.
731 /// This function can be called more than once. In case of a repeated
732 /// call, the previous snapshot gets lost.
733 /// \param _digraph The digraph we make the snapshot of.
734 void save(ListDigraph &_digraph) {
742 /// \brief Undo the changes until the last snapshot.
744 /// Undo the changes until the last snapshot created by save().
747 for(std::list<Arc>::iterator it = added_arcs.begin();
748 it != added_arcs.end(); ++it) {
751 for(std::list<Node>::iterator it = added_nodes.begin();
752 it != added_nodes.end(); ++it) {
758 /// \brief Gives back true when the snapshot is valid.
760 /// Gives back true when the snapshot is valid.
770 class ListGraphBase {
781 int prev_out, next_out;
784 std::vector<NodeT> nodes;
790 std::vector<ArcT> arcs;
796 typedef ListGraphBase Graph;
803 friend class ListGraphBase;
807 explicit Node(int pid) { id = pid;}
811 Node (Invalid) { id = -1; }
812 bool operator==(const Node& node) const {return id == node.id;}
813 bool operator!=(const Node& node) const {return id != node.id;}
814 bool operator<(const Node& node) const {return id < node.id;}
818 friend class ListGraphBase;
822 explicit Edge(int pid) { id = pid;}
826 Edge (Invalid) { id = -1; }
827 bool operator==(const Edge& edge) const {return id == edge.id;}
828 bool operator!=(const Edge& edge) const {return id != edge.id;}
829 bool operator<(const Edge& edge) const {return id < edge.id;}
833 friend class ListGraphBase;
837 explicit Arc(int pid) { id = pid;}
840 operator Edge() const {
841 return id != -1 ? edgeFromId(id / 2) : INVALID;
845 Arc (Invalid) { id = -1; }
846 bool operator==(const Arc& arc) const {return id == arc.id;}
847 bool operator!=(const Arc& arc) const {return id != arc.id;}
848 bool operator<(const Arc& arc) const {return id < arc.id;}
854 : nodes(), first_node(-1),
855 first_free_node(-1), arcs(), first_free_arc(-1) {}
858 int maxNodeId() const { return nodes.size()-1; }
859 int maxEdgeId() const { return arcs.size() / 2 - 1; }
860 int maxArcId() const { return arcs.size()-1; }
862 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
863 Node target(Arc e) const { return Node(arcs[e.id].target); }
865 Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
866 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
868 static bool direction(Arc e) {
869 return (e.id & 1) == 1;
872 static Arc direct(Edge e, bool d) {
873 return Arc(e.id * 2 + (d ? 1 : 0));
876 void first(Node& node) const {
877 node.id = first_node;
880 void next(Node& node) const {
881 node.id = nodes[node.id].next;
884 void first(Arc& e) const {
886 while (n != -1 && nodes[n].first_out == -1) {
889 e.id = (n == -1) ? -1 : nodes[n].first_out;
892 void next(Arc& e) const {
893 if (arcs[e.id].next_out != -1) {
894 e.id = arcs[e.id].next_out;
896 int n = nodes[arcs[e.id ^ 1].target].next;
897 while(n != -1 && nodes[n].first_out == -1) {
900 e.id = (n == -1) ? -1 : nodes[n].first_out;
904 void first(Edge& e) const {
907 e.id = nodes[n].first_out;
908 while ((e.id & 1) != 1) {
909 e.id = arcs[e.id].next_out;
920 void next(Edge& e) const {
921 int n = arcs[e.id * 2].target;
922 e.id = arcs[(e.id * 2) | 1].next_out;
923 while ((e.id & 1) != 1) {
924 e.id = arcs[e.id].next_out;
932 e.id = nodes[n].first_out;
933 while ((e.id & 1) != 1) {
934 e.id = arcs[e.id].next_out;
945 void firstOut(Arc &e, const Node& v) const {
946 e.id = nodes[v.id].first_out;
948 void nextOut(Arc &e) const {
949 e.id = arcs[e.id].next_out;
952 void firstIn(Arc &e, const Node& v) const {
953 e.id = ((nodes[v.id].first_out) ^ 1);
954 if (e.id == -2) e.id = -1;
956 void nextIn(Arc &e) const {
957 e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
958 if (e.id == -2) e.id = -1;
961 void firstInc(Edge &e, bool& d, const Node& v) const {
962 int a = nodes[v.id].first_out;
971 void nextInc(Edge &e, bool& d) const {
972 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
982 static int id(Node v) { return v.id; }
983 static int id(Arc e) { return e.id; }
984 static int id(Edge e) { return e.id; }
986 static Node nodeFromId(int id) { return Node(id);}
987 static Arc arcFromId(int id) { return Arc(id);}
988 static Edge edgeFromId(int id) { return Edge(id);}
990 bool valid(Node n) const {
991 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
992 nodes[n.id].prev != -2;
995 bool valid(Arc a) const {
996 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
997 arcs[a.id].prev_out != -2;
1000 bool valid(Edge e) const {
1001 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1002 arcs[2 * e.id].prev_out != -2;
1008 if(first_free_node==-1) {
1010 nodes.push_back(NodeT());
1012 n = first_free_node;
1013 first_free_node = nodes[n].next;
1016 nodes[n].next = first_node;
1017 if (first_node != -1) nodes[first_node].prev = n;
1021 nodes[n].first_out = -1;
1026 Edge addEdge(Node u, Node v) {
1029 if (first_free_arc == -1) {
1031 arcs.push_back(ArcT());
1032 arcs.push_back(ArcT());
1035 first_free_arc = arcs[n].next_out;
1038 arcs[n].target = u.id;
1039 arcs[n | 1].target = v.id;
1041 arcs[n].next_out = nodes[v.id].first_out;
1042 if (nodes[v.id].first_out != -1) {
1043 arcs[nodes[v.id].first_out].prev_out = n;
1045 arcs[n].prev_out = -1;
1046 nodes[v.id].first_out = n;
1048 arcs[n | 1].next_out = nodes[u.id].first_out;
1049 if (nodes[u.id].first_out != -1) {
1050 arcs[nodes[u.id].first_out].prev_out = (n | 1);
1052 arcs[n | 1].prev_out = -1;
1053 nodes[u.id].first_out = (n | 1);
1058 void erase(const Node& node) {
1061 if(nodes[n].next != -1) {
1062 nodes[nodes[n].next].prev = nodes[n].prev;
1065 if(nodes[n].prev != -1) {
1066 nodes[nodes[n].prev].next = nodes[n].next;
1068 first_node = nodes[n].next;
1071 nodes[n].next = first_free_node;
1072 first_free_node = n;
1076 void erase(const Edge& edge) {
1077 int n = edge.id * 2;
1079 if (arcs[n].next_out != -1) {
1080 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1083 if (arcs[n].prev_out != -1) {
1084 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1086 nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1089 if (arcs[n | 1].next_out != -1) {
1090 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1093 if (arcs[n | 1].prev_out != -1) {
1094 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1096 nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1099 arcs[n].next_out = first_free_arc;
1101 arcs[n].prev_out = -2;
1102 arcs[n | 1].prev_out = -2;
1109 first_node = first_free_node = first_free_arc = -1;
1114 void changeV(Edge e, Node n) {
1115 if(arcs[2 * e.id].next_out != -1) {
1116 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1118 if(arcs[2 * e.id].prev_out != -1) {
1119 arcs[arcs[2 * e.id].prev_out].next_out =
1120 arcs[2 * e.id].next_out;
1122 nodes[arcs[(2 * e.id) | 1].target].first_out =
1123 arcs[2 * e.id].next_out;
1126 if (nodes[n.id].first_out != -1) {
1127 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1129 arcs[(2 * e.id) | 1].target = n.id;
1130 arcs[2 * e.id].prev_out = -1;
1131 arcs[2 * e.id].next_out = nodes[n.id].first_out;
1132 nodes[n.id].first_out = 2 * e.id;
1135 void changeU(Edge e, Node n) {
1136 if(arcs[(2 * e.id) | 1].next_out != -1) {
1137 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1138 arcs[(2 * e.id) | 1].prev_out;
1140 if(arcs[(2 * e.id) | 1].prev_out != -1) {
1141 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1142 arcs[(2 * e.id) | 1].next_out;
1144 nodes[arcs[2 * e.id].target].first_out =
1145 arcs[(2 * e.id) | 1].next_out;
1148 if (nodes[n.id].first_out != -1) {
1149 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1151 arcs[2 * e.id].target = n.id;
1152 arcs[(2 * e.id) | 1].prev_out = -1;
1153 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1154 nodes[n.id].first_out = ((2 * e.id) | 1);
1159 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1162 /// \addtogroup graphs
1165 ///A general undirected graph structure.
1167 ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1168 ///implementation based on static linked lists that are stored in
1169 ///\c std::vector structures.
1171 ///It conforms to the \ref concepts::Graph "Graph concept" and it
1172 ///also provides several useful additional functionalities.
1173 ///Most of the member functions and nested classes are documented
1174 ///only in the concept class.
1176 ///\sa concepts::Graph
1178 class ListGraph : public ExtendedListGraphBase {
1179 typedef ExtendedListGraphBase Parent;
1182 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1184 ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1186 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
1187 ///\brief Assignment of ListGraph to another one is \e not allowed.
1188 ///Use copyGraph() instead.
1190 ///Assignment of ListGraph to another one is \e not allowed.
1191 ///Use copyGraph() instead.
1192 void operator=(const ListGraph &) {}
1200 typedef Parent::OutArcIt IncEdgeIt;
1202 /// \brief Add a new node to the graph.
1204 /// Add a new node to the graph.
1205 /// \return The new node.
1206 Node addNode() { return Parent::addNode(); }
1208 /// \brief Add a new edge to the graph.
1210 /// Add a new edge to the graph with source node \c s
1211 /// and target node \c t.
1212 /// \return The new edge.
1213 Edge addEdge(const Node& s, const Node& t) {
1214 return Parent::addEdge(s, t);
1217 /// \brief Erase a node from the graph.
1219 /// Erase a node from the graph.
1221 void erase(const Node& n) { Parent::erase(n); }
1223 /// \brief Erase an edge from the graph.
1225 /// Erase an edge from the graph.
1227 void erase(const Edge& e) { Parent::erase(e); }
1228 /// Node validity check
1230 /// This function gives back true if the given node is valid,
1231 /// ie. it is a real node of the graph.
1233 /// \warning A Node pointing to a removed item
1234 /// could become valid again later if new nodes are
1235 /// added to the graph.
1236 bool valid(Node n) const { return Parent::valid(n); }
1237 /// Arc validity check
1239 /// This function gives back true if the given arc is valid,
1240 /// ie. it is a real arc of the graph.
1242 /// \warning An Arc pointing to a removed item
1243 /// could become valid again later if new edges are
1244 /// added to the graph.
1245 bool valid(Arc a) const { return Parent::valid(a); }
1246 /// Edge validity check
1248 /// This function gives back true if the given edge is valid,
1249 /// ie. it is a real arc of the graph.
1251 /// \warning A Edge pointing to a removed item
1252 /// could become valid again later if new edges are
1253 /// added to the graph.
1254 bool valid(Edge e) const { return Parent::valid(e); }
1255 /// \brief Change the end \c u of \c e to \c n
1257 /// This function changes the end \c u of \c e to node \c n.
1259 ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1260 ///changed edge are invalidated and if the changed node is the
1261 ///base node of an iterator then this iterator is also
1264 ///\warning This functionality cannot be used together with the
1265 ///Snapshot feature.
1266 void changeU(Edge e, Node n) {
1267 Parent::changeU(e,n);
1269 /// \brief Change the end \c v of \c e to \c n
1271 /// This function changes the end \c v of \c e to \c n.
1273 ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1274 ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1275 ///base node of an iterator then this iterator is invalidated.
1277 ///\warning This functionality cannot be used together with the
1278 ///Snapshot feature.
1279 void changeV(Edge e, Node n) {
1280 Parent::changeV(e,n);
1282 /// \brief Contract two nodes.
1284 /// This function contracts two nodes.
1285 /// Node \p b will be removed but instead of deleting
1286 /// its neighboring arcs, they will be joined to \p a.
1287 /// The last parameter \p r controls whether to remove loops. \c true
1288 /// means that loops will be removed.
1290 /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1293 ///\warning This functionality cannot be used together with the
1294 ///Snapshot feature.
1295 void contract(Node a, Node b, bool r = true) {
1296 for(IncEdgeIt e(*this, b); e!=INVALID;) {
1297 IncEdgeIt f = e; ++f;
1298 if (r && runningNode(e) == a) {
1300 } else if (u(e) == b) {
1311 /// \brief Class to make a snapshot of the graph and restore
1314 /// Class to make a snapshot of the graph and restore it later.
1316 /// The newly added nodes and edges can be removed
1317 /// using the restore() function.
1319 /// \warning Edge and node deletions and other modifications
1320 /// (e.g. changing nodes of edges, contracting nodes) cannot be
1321 /// restored. These events invalidate the snapshot.
1325 typedef Parent::NodeNotifier NodeNotifier;
1327 class NodeObserverProxy : public NodeNotifier::ObserverBase {
1330 NodeObserverProxy(Snapshot& _snapshot)
1331 : snapshot(_snapshot) {}
1333 using NodeNotifier::ObserverBase::attach;
1334 using NodeNotifier::ObserverBase::detach;
1335 using NodeNotifier::ObserverBase::attached;
1339 virtual void add(const Node& node) {
1340 snapshot.addNode(node);
1342 virtual void add(const std::vector<Node>& nodes) {
1343 for (int i = nodes.size() - 1; i >= 0; ++i) {
1344 snapshot.addNode(nodes[i]);
1347 virtual void erase(const Node& node) {
1348 snapshot.eraseNode(node);
1350 virtual void erase(const std::vector<Node>& nodes) {
1351 for (int i = 0; i < int(nodes.size()); ++i) {
1352 snapshot.eraseNode(nodes[i]);
1355 virtual void build() {
1357 std::vector<Node> nodes;
1358 for (notifier()->first(node); node != INVALID;
1359 notifier()->next(node)) {
1360 nodes.push_back(node);
1362 for (int i = nodes.size() - 1; i >= 0; --i) {
1363 snapshot.addNode(nodes[i]);
1366 virtual void clear() {
1368 for (notifier()->first(node); node != INVALID;
1369 notifier()->next(node)) {
1370 snapshot.eraseNode(node);
1377 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1380 EdgeObserverProxy(Snapshot& _snapshot)
1381 : snapshot(_snapshot) {}
1383 using EdgeNotifier::ObserverBase::attach;
1384 using EdgeNotifier::ObserverBase::detach;
1385 using EdgeNotifier::ObserverBase::attached;
1389 virtual void add(const Edge& edge) {
1390 snapshot.addEdge(edge);
1392 virtual void add(const std::vector<Edge>& edges) {
1393 for (int i = edges.size() - 1; i >= 0; ++i) {
1394 snapshot.addEdge(edges[i]);
1397 virtual void erase(const Edge& edge) {
1398 snapshot.eraseEdge(edge);
1400 virtual void erase(const std::vector<Edge>& edges) {
1401 for (int i = 0; i < int(edges.size()); ++i) {
1402 snapshot.eraseEdge(edges[i]);
1405 virtual void build() {
1407 std::vector<Edge> edges;
1408 for (notifier()->first(edge); edge != INVALID;
1409 notifier()->next(edge)) {
1410 edges.push_back(edge);
1412 for (int i = edges.size() - 1; i >= 0; --i) {
1413 snapshot.addEdge(edges[i]);
1416 virtual void clear() {
1418 for (notifier()->first(edge); edge != INVALID;
1419 notifier()->next(edge)) {
1420 snapshot.eraseEdge(edge);
1429 NodeObserverProxy node_observer_proxy;
1430 EdgeObserverProxy edge_observer_proxy;
1432 std::list<Node> added_nodes;
1433 std::list<Edge> added_edges;
1436 void addNode(const Node& node) {
1437 added_nodes.push_front(node);
1439 void eraseNode(const Node& node) {
1440 std::list<Node>::iterator it =
1441 std::find(added_nodes.begin(), added_nodes.end(), node);
1442 if (it == added_nodes.end()) {
1444 edge_observer_proxy.detach();
1445 throw NodeNotifier::ImmediateDetach();
1447 added_nodes.erase(it);
1451 void addEdge(const Edge& edge) {
1452 added_edges.push_front(edge);
1454 void eraseEdge(const Edge& edge) {
1455 std::list<Edge>::iterator it =
1456 std::find(added_edges.begin(), added_edges.end(), edge);
1457 if (it == added_edges.end()) {
1459 node_observer_proxy.detach();
1460 throw EdgeNotifier::ImmediateDetach();
1462 added_edges.erase(it);
1466 void attach(ListGraph &_graph) {
1468 node_observer_proxy.attach(graph->notifier(Node()));
1469 edge_observer_proxy.attach(graph->notifier(Edge()));
1473 node_observer_proxy.detach();
1474 edge_observer_proxy.detach();
1477 bool attached() const {
1478 return node_observer_proxy.attached();
1482 added_nodes.clear();
1483 added_edges.clear();
1488 /// \brief Default constructor.
1490 /// Default constructor.
1491 /// To actually make a snapshot you must call save().
1493 : graph(0), node_observer_proxy(*this),
1494 edge_observer_proxy(*this) {}
1496 /// \brief Constructor that immediately makes a snapshot.
1498 /// This constructor immediately makes a snapshot of the graph.
1499 /// \param _graph The graph we make a snapshot of.
1500 Snapshot(ListGraph &_graph)
1501 : node_observer_proxy(*this),
1502 edge_observer_proxy(*this) {
1506 /// \brief Make a snapshot.
1508 /// Make a snapshot of the graph.
1510 /// This function can be called more than once. In case of a repeated
1511 /// call, the previous snapshot gets lost.
1512 /// \param _graph The graph we make the snapshot of.
1513 void save(ListGraph &_graph) {
1521 /// \brief Undo the changes until the last snapshot.
1523 /// Undo the changes until the last snapshot created by save().
1526 for(std::list<Edge>::iterator it = added_edges.begin();
1527 it != added_edges.end(); ++it) {
1530 for(std::list<Node>::iterator it = added_nodes.begin();
1531 it != added_nodes.end(); ++it) {
1537 /// \brief Gives back true when the snapshot is valid.
1539 /// Gives back true when the snapshot is valid.
1540 bool valid() const {