Digraph and Graph concept should be conform to the IDable... 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& e) const {
117 n!=-1 && nodes[n].first_in == -1;
119 e.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 digraphs
299 ///A list digraph class.
301 ///This is a simple and fast digraph implementation.
303 ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
304 ///also provides several additional useful extra functionalities.
305 ///The most of the member functions and nested classes are
306 ///documented only in the concept class.
308 ///An important extra feature of this digraph implementation is that
309 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
311 ///\sa concepts::Digraph.
313 class ListDigraph : public ExtendedListDigraphBase {
315 ///ListDigraph is \e not copy constructible. Use DigraphCopy() instead.
317 ///ListDigraph is \e not copy constructible. Use DigraphCopy() instead.
319 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
320 ///\brief Assignment of ListDigraph to another one is \e not allowed.
321 ///Use DigraphCopy() instead.
323 ///Assignment of ListDigraph to another one is \e not allowed.
324 ///Use DigraphCopy() instead.
325 void operator=(const ListDigraph &) {}
328 typedef ExtendedListDigraphBase Parent;
336 ///Add a new node to the digraph.
338 /// \return the new node.
340 Node addNode() { return Parent::addNode(); }
342 ///Add a new arc to the digraph.
344 ///Add a new arc to the digraph with source node \c s
345 ///and target node \c t.
346 ///\return the new arc.
347 Arc addArc(const Node& s, const Node& t) {
348 return Parent::addArc(s, t);
351 /// Changes the target of \c e to \c n
353 /// Changes the target of \c e to \c n
355 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
356 ///the changed arc remain valid. However <tt>InArcIt</tt>s are
358 ///\warning This functionality cannot be used together with the Snapshot
360 void changeTarget(Arc e, Node n) {
361 Parent::changeTarget(e,n);
363 /// Changes the source of \c e to \c n
365 /// Changes the source of \c e to \c n
367 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
368 ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
370 ///\warning This functionality cannot be used together with the Snapshot
372 void changeSource(Arc e, Node n) {
373 Parent::changeSource(e,n);
376 /// Invert the direction of an arc.
378 ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
379 ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
381 ///\warning This functionality cannot be used together with the Snapshot
383 void reverseArc(Arc e) {
385 changeTarget(e,source(e));
389 /// Using this it is possible to avoid the superfluous memory
390 /// allocation: if you know that the digraph you want to build will
391 /// be very large (e.g. it will contain millions of nodes and/or arcs)
392 /// then it is worth reserving space for this amount before starting
393 /// to build the digraph.
395 void reserveNode(int n) { nodes.reserve(n); };
397 /// \brief Using this it is possible to avoid the superfluous memory
400 /// Using this it is possible to avoid the superfluous memory
401 /// allocation: if you know that the digraph you want to build will
402 /// be very large (e.g. it will contain millions of nodes and/or arcs)
403 /// then it is worth reserving space for this amount before starting
404 /// to build the digraph.
406 void reserveArc(int m) { arcs.reserve(m); };
408 ///Contract two nodes.
410 ///This function contracts two nodes.
412 ///Node \p b will be removed but instead of deleting
413 ///incident arcs, they will be joined to \p a.
414 ///The last parameter \p r controls whether to remove loops. \c true
415 ///means that loops will be removed.
417 ///\note The <tt>ArcIt</tt>s
418 ///referencing a moved arc remain
419 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
420 ///may be invalidated.
421 ///\warning This functionality cannot be used together with the Snapshot
423 void contract(Node a, Node b, bool r = true)
425 for(OutArcIt e(*this,b);e!=INVALID;) {
428 if(r && target(e)==a) erase(e);
429 else changeSource(e,a);
432 for(InArcIt e(*this,b);e!=INVALID;) {
435 if(r && source(e)==a) erase(e);
436 else changeTarget(e,a);
444 ///This function splits a node. First a new node is added to the digraph,
445 ///then the source of each outgoing arc of \c n is moved to this new node.
446 ///If \c connect is \c true (this is the default value), then a new arc
447 ///from \c n to the newly created node is also added.
448 ///\return The newly created node.
450 ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
451 ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
454 ///\warning This functionality cannot be used together with the
455 ///Snapshot feature. \todo It could be implemented in a bit
457 Node split(Node n, bool connect = true) {
459 for(OutArcIt e(*this,n);e!=INVALID;) {
465 if (connect) addArc(n,b);
471 ///This function splits an arc. First a new node \c b is added to
472 ///the digraph, then the original arc is re-targeted to \c
473 ///b. Finally an arc from \c b to the original target is added.
474 ///\return The newly created node.
475 ///\warning This functionality
476 ///cannot be used together with the Snapshot feature.
484 /// \brief Class to make a snapshot of the digraph and restore
487 /// Class to make a snapshot of the digraph and to restore it
490 /// The newly added nodes and arcs can be removed using the
491 /// restore() function.
493 /// \warning Arc and node deletions cannot be restored. This
494 /// events invalidate the snapshot.
498 typedef Parent::NodeNotifier NodeNotifier;
500 class NodeObserverProxy : public NodeNotifier::ObserverBase {
503 NodeObserverProxy(Snapshot& _snapshot)
504 : snapshot(_snapshot) {}
506 using NodeNotifier::ObserverBase::attach;
507 using NodeNotifier::ObserverBase::detach;
508 using NodeNotifier::ObserverBase::attached;
512 virtual void add(const Node& node) {
513 snapshot.addNode(node);
515 virtual void add(const std::vector<Node>& nodes) {
516 for (int i = nodes.size() - 1; i >= 0; ++i) {
517 snapshot.addNode(nodes[i]);
520 virtual void erase(const Node& node) {
521 snapshot.eraseNode(node);
523 virtual void erase(const std::vector<Node>& nodes) {
524 for (int i = 0; i < int(nodes.size()); ++i) {
525 snapshot.eraseNode(nodes[i]);
528 virtual void build() {
530 std::vector<Node> nodes;
531 for (notifier()->first(node); node != INVALID;
532 notifier()->next(node)) {
533 nodes.push_back(node);
535 for (int i = nodes.size() - 1; i >= 0; --i) {
536 snapshot.addNode(nodes[i]);
539 virtual void clear() {
541 for (notifier()->first(node); node != INVALID;
542 notifier()->next(node)) {
543 snapshot.eraseNode(node);
550 class ArcObserverProxy : public ArcNotifier::ObserverBase {
553 ArcObserverProxy(Snapshot& _snapshot)
554 : snapshot(_snapshot) {}
556 using ArcNotifier::ObserverBase::attach;
557 using ArcNotifier::ObserverBase::detach;
558 using ArcNotifier::ObserverBase::attached;
562 virtual void add(const Arc& arc) {
563 snapshot.addArc(arc);
565 virtual void add(const std::vector<Arc>& arcs) {
566 for (int i = arcs.size() - 1; i >= 0; ++i) {
567 snapshot.addArc(arcs[i]);
570 virtual void erase(const Arc& arc) {
571 snapshot.eraseArc(arc);
573 virtual void erase(const std::vector<Arc>& arcs) {
574 for (int i = 0; i < int(arcs.size()); ++i) {
575 snapshot.eraseArc(arcs[i]);
578 virtual void build() {
580 std::vector<Arc> arcs;
581 for (notifier()->first(arc); arc != INVALID;
582 notifier()->next(arc)) {
585 for (int i = arcs.size() - 1; i >= 0; --i) {
586 snapshot.addArc(arcs[i]);
589 virtual void clear() {
591 for (notifier()->first(arc); arc != INVALID;
592 notifier()->next(arc)) {
593 snapshot.eraseArc(arc);
600 ListDigraph *digraph;
602 NodeObserverProxy node_observer_proxy;
603 ArcObserverProxy arc_observer_proxy;
605 std::list<Node> added_nodes;
606 std::list<Arc> added_arcs;
609 void addNode(const Node& node) {
610 added_nodes.push_front(node);
612 void eraseNode(const Node& node) {
613 std::list<Node>::iterator it =
614 std::find(added_nodes.begin(), added_nodes.end(), node);
615 if (it == added_nodes.end()) {
617 arc_observer_proxy.detach();
618 throw NodeNotifier::ImmediateDetach();
620 added_nodes.erase(it);
624 void addArc(const Arc& arc) {
625 added_arcs.push_front(arc);
627 void eraseArc(const Arc& arc) {
628 std::list<Arc>::iterator it =
629 std::find(added_arcs.begin(), added_arcs.end(), arc);
630 if (it == added_arcs.end()) {
632 node_observer_proxy.detach();
633 throw ArcNotifier::ImmediateDetach();
635 added_arcs.erase(it);
639 void attach(ListDigraph &_digraph) {
641 node_observer_proxy.attach(digraph->notifier(Node()));
642 arc_observer_proxy.attach(digraph->notifier(Arc()));
646 node_observer_proxy.detach();
647 arc_observer_proxy.detach();
650 bool attached() const {
651 return node_observer_proxy.attached();
661 /// \brief Default constructor.
663 /// Default constructor.
664 /// To actually make a snapshot you must call save().
666 : digraph(0), node_observer_proxy(*this),
667 arc_observer_proxy(*this) {}
669 /// \brief Constructor that immediately makes a snapshot.
671 /// This constructor immediately makes a snapshot of the digraph.
672 /// \param _digraph The digraph we make a snapshot of.
673 Snapshot(ListDigraph &_digraph)
674 : node_observer_proxy(*this),
675 arc_observer_proxy(*this) {
679 /// \brief Make a snapshot.
681 /// Make a snapshot of the digraph.
683 /// This function can be called more than once. In case of a repeated
684 /// call, the previous snapshot gets lost.
685 /// \param _digraph The digraph we make the snapshot of.
686 void save(ListDigraph &_digraph) {
694 /// \brief Undo the changes until the last snapshot.
696 /// Undo the changes until the last snapshot created by save().
699 for(std::list<Arc>::iterator it = added_arcs.begin();
700 it != added_arcs.end(); ++it) {
703 for(std::list<Node>::iterator it = added_nodes.begin();
704 it != added_nodes.end(); ++it) {
710 /// \brief Gives back true when the snapshot is valid.
712 /// Gives back true when the snapshot is valid.
722 class ListGraphBase {
733 int prev_out, next_out;
736 std::vector<NodeT> nodes;
742 std::vector<ArcT> arcs;
748 typedef ListGraphBase Digraph;
755 friend class ListGraphBase;
759 explicit Node(int pid) { id = pid;}
763 Node (Invalid) { id = -1; }
764 bool operator==(const Node& node) const {return id == node.id;}
765 bool operator!=(const Node& node) const {return id != node.id;}
766 bool operator<(const Node& node) const {return id < node.id;}
770 friend class ListGraphBase;
774 explicit Edge(int pid) { id = pid;}
778 Edge (Invalid) { id = -1; }
779 bool operator==(const Edge& arc) const {return id == arc.id;}
780 bool operator!=(const Edge& arc) const {return id != arc.id;}
781 bool operator<(const Edge& arc) const {return id < arc.id;}
785 friend class ListGraphBase;
789 explicit Arc(int pid) { id = pid;}
792 operator Edge() const { return edgeFromId(id / 2); }
795 Arc (Invalid) { id = -1; }
796 bool operator==(const Arc& arc) const {return id == arc.id;}
797 bool operator!=(const Arc& arc) const {return id != arc.id;}
798 bool operator<(const Arc& arc) const {return id < arc.id;}
804 : nodes(), first_node(-1),
805 first_free_node(-1), arcs(), first_free_arc(-1) {}
808 int maxNodeId() const { return nodes.size()-1; }
809 int maxEdgeId() const { return arcs.size() / 2 - 1; }
810 int maxArcId() const { return arcs.size()-1; }
812 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
813 Node target(Arc e) const { return Node(arcs[e.id].target); }
815 Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
816 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
818 static bool direction(Arc e) {
819 return (e.id & 1) == 1;
822 static Arc direct(Edge e, bool d) {
823 return Arc(e.id * 2 + (d ? 1 : 0));
826 void first(Node& node) const {
827 node.id = first_node;
830 void next(Node& node) const {
831 node.id = nodes[node.id].next;
834 void first(Arc& e) const {
836 while (n != -1 && nodes[n].first_out == -1) {
839 e.id = (n == -1) ? -1 : nodes[n].first_out;
842 void next(Arc& e) const {
843 if (arcs[e.id].next_out != -1) {
844 e.id = arcs[e.id].next_out;
846 int n = nodes[arcs[e.id ^ 1].target].next;
847 while(n != -1 && nodes[n].first_out == -1) {
850 e.id = (n == -1) ? -1 : nodes[n].first_out;
854 void first(Edge& e) const {
857 e.id = nodes[n].first_out;
858 while ((e.id & 1) != 1) {
859 e.id = arcs[e.id].next_out;
870 void next(Edge& e) const {
871 int n = arcs[e.id * 2].target;
872 e.id = arcs[(e.id * 2) | 1].next_out;
873 while ((e.id & 1) != 1) {
874 e.id = arcs[e.id].next_out;
882 e.id = nodes[n].first_out;
883 while ((e.id & 1) != 1) {
884 e.id = arcs[e.id].next_out;
895 void firstOut(Arc &e, const Node& v) const {
896 e.id = nodes[v.id].first_out;
898 void nextOut(Arc &e) const {
899 e.id = arcs[e.id].next_out;
902 void firstIn(Arc &e, const Node& v) const {
903 e.id = ((nodes[v.id].first_out) ^ 1);
904 if (e.id == -2) e.id = -1;
906 void nextIn(Arc &e) const {
907 e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
908 if (e.id == -2) e.id = -1;
911 void firstInc(Edge &e, bool& d, const Node& v) const {
912 int de = nodes[v.id].first_out;
921 void nextInc(Edge &e, bool& d) const {
922 int de = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
932 static int id(Node v) { return v.id; }
933 static int id(Arc e) { return e.id; }
934 static int id(Edge e) { return e.id; }
936 static Node nodeFromId(int id) { return Node(id);}
937 static Arc arcFromId(int id) { return Arc(id);}
938 static Edge edgeFromId(int id) { return Edge(id);}
943 if(first_free_node==-1) {
945 nodes.push_back(NodeT());
948 first_free_node = nodes[n].next;
951 nodes[n].next = first_node;
952 if (first_node != -1) nodes[first_node].prev = n;
956 nodes[n].first_out = -1;
961 Edge addEdge(Node u, Node v) {
964 if (first_free_arc == -1) {
966 arcs.push_back(ArcT());
967 arcs.push_back(ArcT());
970 first_free_arc = arcs[n].next_out;
973 arcs[n].target = u.id;
974 arcs[n | 1].target = v.id;
976 arcs[n].next_out = nodes[v.id].first_out;
977 if (nodes[v.id].first_out != -1) {
978 arcs[nodes[v.id].first_out].prev_out = n;
980 arcs[n].prev_out = -1;
981 nodes[v.id].first_out = n;
983 arcs[n | 1].next_out = nodes[u.id].first_out;
984 if (nodes[u.id].first_out != -1) {
985 arcs[nodes[u.id].first_out].prev_out = (n | 1);
987 arcs[n | 1].prev_out = -1;
988 nodes[u.id].first_out = (n | 1);
993 void erase(const Node& node) {
996 if(nodes[n].next != -1) {
997 nodes[nodes[n].next].prev = nodes[n].prev;
1000 if(nodes[n].prev != -1) {
1001 nodes[nodes[n].prev].next = nodes[n].next;
1003 first_node = nodes[n].next;
1006 nodes[n].next = first_free_node;
1007 first_free_node = n;
1011 void erase(const Edge& arc) {
1014 if (arcs[n].next_out != -1) {
1015 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1018 if (arcs[n].prev_out != -1) {
1019 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1021 nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1024 if (arcs[n | 1].next_out != -1) {
1025 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1028 if (arcs[n | 1].prev_out != -1) {
1029 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1031 nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1034 arcs[n].next_out = first_free_arc;
1042 first_node = first_free_node = first_free_arc = -1;
1047 void changeTarget(Edge e, Node n) {
1048 if(arcs[2 * e.id].next_out != -1) {
1049 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1051 if(arcs[2 * e.id].prev_out != -1) {
1052 arcs[arcs[2 * e.id].prev_out].next_out =
1053 arcs[2 * e.id].next_out;
1055 nodes[arcs[(2 * e.id) | 1].target].first_out =
1056 arcs[2 * e.id].next_out;
1059 if (nodes[n.id].first_out != -1) {
1060 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1062 arcs[(2 * e.id) | 1].target = n.id;
1063 arcs[2 * e.id].prev_out = -1;
1064 arcs[2 * e.id].next_out = nodes[n.id].first_out;
1065 nodes[n.id].first_out = 2 * e.id;
1068 void changeSource(Edge e, Node n) {
1069 if(arcs[(2 * e.id) | 1].next_out != -1) {
1070 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1071 arcs[(2 * e.id) | 1].prev_out;
1073 if(arcs[(2 * e.id) | 1].prev_out != -1) {
1074 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1075 arcs[(2 * e.id) | 1].next_out;
1077 nodes[arcs[2 * e.id].target].first_out =
1078 arcs[(2 * e.id) | 1].next_out;
1081 if (nodes[n.id].first_out != -1) {
1082 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1084 arcs[2 * e.id].target = n.id;
1085 arcs[(2 * e.id) | 1].prev_out = -1;
1086 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1087 nodes[n.id].first_out = ((2 * e.id) | 1);
1092 // typedef GraphExtender<UndirDigraphExtender<ListDigraphBase> >
1093 // ExtendedListGraphBase;
1095 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1099 /// \addtogroup digraphs
1102 ///An undirected list digraph class.
1104 ///This is a simple and fast undirected digraph implementation.
1106 ///An important extra feature of this digraph implementation is that
1107 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1109 ///It conforms to the
1110 ///\ref concepts::Graph "Graph concept".
1112 ///\sa concepts::Graph.
1114 class ListGraph : public ExtendedListGraphBase {
1116 ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
1118 ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
1120 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
1121 ///\brief Assignment of ListGraph to another one is \e not allowed.
1122 ///Use GraphCopy() instead.
1124 ///Assignment of ListGraph to another one is \e not allowed.
1125 ///Use GraphCopy() instead.
1126 void operator=(const ListGraph &) {}
1134 typedef ExtendedListGraphBase Parent;
1136 typedef Parent::OutArcIt IncArcIt;
1138 /// \brief Add a new node to the digraph.
1140 /// \return the new node.
1142 Node addNode() { return Parent::addNode(); }
1144 /// \brief Add a new edge to the digraph.
1146 /// Add a new arc to the digraph with source node \c s
1147 /// and target node \c t.
1148 /// \return the new edge.
1149 Edge addEdge(const Node& s, const Node& t) {
1150 return Parent::addEdge(s, t);
1152 /// \brief Changes the source of \c e to \c n
1154 /// Changes the source of \c e to \c n
1156 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1157 ///referencing the changed arc remain
1158 ///valid. However <tt>OutArcIt</tt>s are invalidated.
1159 void changeSource(Edge e, Node n) {
1160 Parent::changeSource(e,n);
1162 /// \brief Changes the target of \c e to \c n
1164 /// Changes the target of \c e to \c n
1166 /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1167 /// valid. However the other iterators may be invalidated.
1168 void changeTarget(Edge e, Node n) {
1169 Parent::changeTarget(e,n);
1171 /// \brief Changes the source of \c e to \c n
1173 /// Changes the source of \c e to \c n. It changes the proper
1174 /// node of the represented edge.
1176 ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1177 ///referencing the changed arc remain
1178 ///valid. However <tt>OutArcIt</tt>s are invalidated.
1179 void changeSource(Arc e, Node n) {
1180 if (Parent::direction(e)) {
1181 Parent::changeSource(e,n);
1183 Parent::changeTarget(e,n);
1186 /// \brief Changes the target of \c e to \c n
1188 /// Changes the target of \c e to \c n. It changes the proper
1189 /// node of the represented edge.
1191 ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
1192 ///referencing the changed arc remain
1193 ///valid. However <tt>InArcIt</tt>s are invalidated.
1194 void changeTarget(Arc e, Node n) {
1195 if (Parent::direction(e)) {
1196 Parent::changeTarget(e,n);
1198 Parent::changeSource(e,n);
1201 /// \brief Contract two nodes.
1203 /// This function contracts two nodes.
1205 /// Node \p b will be removed but instead of deleting
1206 /// its neighboring arcs, they will be joined to \p a.
1207 /// The last parameter \p r controls whether to remove loops. \c true
1208 /// means that loops will be removed.
1210 /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1212 void contract(Node a, Node b, bool r = true) {
1213 for(IncArcIt e(*this, b); e!=INVALID;) {
1214 IncArcIt f = e; ++f;
1215 if (r && runningNode(e) == a) {
1217 } else if (source(e) == b) {
1228 /// \brief Class to make a snapshot of the digraph and restore
1231 /// Class to make a snapshot of the digraph and to restore it
1234 /// The newly added nodes and edges can be removed
1235 /// using the restore() function.
1237 /// \warning Arc and node deletions cannot be restored. This
1238 /// events invalidate the snapshot.
1242 typedef Parent::NodeNotifier NodeNotifier;
1244 class NodeObserverProxy : public NodeNotifier::ObserverBase {
1247 NodeObserverProxy(Snapshot& _snapshot)
1248 : snapshot(_snapshot) {}
1250 using NodeNotifier::ObserverBase::attach;
1251 using NodeNotifier::ObserverBase::detach;
1252 using NodeNotifier::ObserverBase::attached;
1256 virtual void add(const Node& node) {
1257 snapshot.addNode(node);
1259 virtual void add(const std::vector<Node>& nodes) {
1260 for (int i = nodes.size() - 1; i >= 0; ++i) {
1261 snapshot.addNode(nodes[i]);
1264 virtual void erase(const Node& node) {
1265 snapshot.eraseNode(node);
1267 virtual void erase(const std::vector<Node>& nodes) {
1268 for (int i = 0; i < int(nodes.size()); ++i) {
1269 snapshot.eraseNode(nodes[i]);
1272 virtual void build() {
1274 std::vector<Node> nodes;
1275 for (notifier()->first(node); node != INVALID;
1276 notifier()->next(node)) {
1277 nodes.push_back(node);
1279 for (int i = nodes.size() - 1; i >= 0; --i) {
1280 snapshot.addNode(nodes[i]);
1283 virtual void clear() {
1285 for (notifier()->first(node); node != INVALID;
1286 notifier()->next(node)) {
1287 snapshot.eraseNode(node);
1294 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1297 EdgeObserverProxy(Snapshot& _snapshot)
1298 : snapshot(_snapshot) {}
1300 using EdgeNotifier::ObserverBase::attach;
1301 using EdgeNotifier::ObserverBase::detach;
1302 using EdgeNotifier::ObserverBase::attached;
1306 virtual void add(const Edge& arc) {
1307 snapshot.addEdge(arc);
1309 virtual void add(const std::vector<Edge>& arcs) {
1310 for (int i = arcs.size() - 1; i >= 0; ++i) {
1311 snapshot.addEdge(arcs[i]);
1314 virtual void erase(const Edge& arc) {
1315 snapshot.eraseEdge(arc);
1317 virtual void erase(const std::vector<Edge>& arcs) {
1318 for (int i = 0; i < int(arcs.size()); ++i) {
1319 snapshot.eraseEdge(arcs[i]);
1322 virtual void build() {
1324 std::vector<Edge> arcs;
1325 for (notifier()->first(arc); arc != INVALID;
1326 notifier()->next(arc)) {
1327 arcs.push_back(arc);
1329 for (int i = arcs.size() - 1; i >= 0; --i) {
1330 snapshot.addEdge(arcs[i]);
1333 virtual void clear() {
1335 for (notifier()->first(arc); arc != INVALID;
1336 notifier()->next(arc)) {
1337 snapshot.eraseEdge(arc);
1346 NodeObserverProxy node_observer_proxy;
1347 EdgeObserverProxy arc_observer_proxy;
1349 std::list<Node> added_nodes;
1350 std::list<Edge> added_arcs;
1353 void addNode(const Node& node) {
1354 added_nodes.push_front(node);
1356 void eraseNode(const Node& node) {
1357 std::list<Node>::iterator it =
1358 std::find(added_nodes.begin(), added_nodes.end(), node);
1359 if (it == added_nodes.end()) {
1361 arc_observer_proxy.detach();
1362 throw NodeNotifier::ImmediateDetach();
1364 added_nodes.erase(it);
1368 void addEdge(const Edge& arc) {
1369 added_arcs.push_front(arc);
1371 void eraseEdge(const Edge& arc) {
1372 std::list<Edge>::iterator it =
1373 std::find(added_arcs.begin(), added_arcs.end(), arc);
1374 if (it == added_arcs.end()) {
1376 node_observer_proxy.detach();
1377 throw EdgeNotifier::ImmediateDetach();
1379 added_arcs.erase(it);
1383 void attach(ListGraph &_digraph) {
1384 digraph = &_digraph;
1385 node_observer_proxy.attach(digraph->notifier(Node()));
1386 arc_observer_proxy.attach(digraph->notifier(Edge()));
1390 node_observer_proxy.detach();
1391 arc_observer_proxy.detach();
1394 bool attached() const {
1395 return node_observer_proxy.attached();
1399 added_nodes.clear();
1405 /// \brief Default constructor.
1407 /// Default constructor.
1408 /// To actually make a snapshot you must call save().
1410 : digraph(0), node_observer_proxy(*this),
1411 arc_observer_proxy(*this) {}
1413 /// \brief Constructor that immediately makes a snapshot.
1415 /// This constructor immediately makes a snapshot of the digraph.
1416 /// \param _digraph The digraph we make a snapshot of.
1417 Snapshot(ListGraph &_digraph)
1418 : node_observer_proxy(*this),
1419 arc_observer_proxy(*this) {
1423 /// \brief Make a snapshot.
1425 /// Make a snapshot of the digraph.
1427 /// This function can be called more than once. In case of a repeated
1428 /// call, the previous snapshot gets lost.
1429 /// \param _digraph The digraph we make the snapshot of.
1430 void save(ListGraph &_digraph) {
1438 /// \brief Undo the changes until the last snapshot.
1440 /// Undo the changes until the last snapshot created by save().
1443 for(std::list<Edge>::iterator it = added_arcs.begin();
1444 it != added_arcs.end(); ++it) {
1445 digraph->erase(*it);
1447 for(std::list<Node>::iterator it = added_nodes.begin();
1448 it != added_nodes.end(); ++it) {
1449 digraph->erase(*it);
1454 /// \brief Gives back true when the snapshot is valid.
1456 /// Gives back true when the snapshot is valid.
1457 bool valid() const {