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 and 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 versatile and fast directed graph
315 ///implementation based on linked lists that are stored in
316 ///\c std::vector structures.
318 ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
319 ///and it also provides several useful additional functionalities.
320 ///Most of its 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 /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
330 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
331 /// \brief Assignment of a digraph to another one is \e not allowed.
332 /// Use DigraphCopy instead.
333 void operator=(const ListDigraph &) {}
342 ///Add a new node to the digraph.
344 ///This function adds a new node to the digraph.
345 ///\return The new node.
346 Node addNode() { return Parent::addNode(); }
348 ///Add a new arc to the digraph.
350 ///This function adds a new arc to the digraph with source node \c s
351 ///and target node \c t.
352 ///\return The new arc.
353 Arc addArc(Node s, Node t) {
354 return Parent::addArc(s, t);
357 ///\brief Erase a node from the digraph.
359 ///This function erases the given node from the digraph.
360 void erase(Node n) { Parent::erase(n); }
362 ///\brief Erase an arc from the digraph.
364 ///This function erases the given arc from the digraph.
365 void erase(Arc a) { Parent::erase(a); }
367 /// Node validity check
369 /// This function gives back \c true if the given node is valid,
370 /// i.e. it is a real node of the digraph.
372 /// \warning A removed node could become valid again if new nodes are
373 /// added to the digraph.
374 bool valid(Node n) const { return Parent::valid(n); }
376 /// Arc validity check
378 /// This function gives back \c true if the given arc is valid,
379 /// i.e. it is a real arc of the digraph.
381 /// \warning A removed arc could become valid again if new arcs are
382 /// added to the digraph.
383 bool valid(Arc a) const { return Parent::valid(a); }
385 /// Change the target node of an arc
387 /// This function changes the target node of the given arc \c a to \c n.
389 ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
390 ///arc remain valid, however \c InArcIt iterators are invalidated.
392 ///\warning This functionality cannot be used together with the Snapshot
394 void changeTarget(Arc a, Node n) {
395 Parent::changeTarget(a,n);
397 /// Change the source node of an arc
399 /// This function changes the source node of the given arc \c a to \c n.
401 ///\note \c InArcIt iterators referencing the changed arc remain
402 ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
404 ///\warning This functionality cannot be used together with the Snapshot
406 void changeSource(Arc a, Node n) {
407 Parent::changeSource(a,n);
410 /// Reverse the direction of an arc.
412 /// This function reverses the direction of the given arc.
413 ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
414 ///the changed arc are invalidated.
416 ///\warning This functionality cannot be used together with the Snapshot
418 void reverseArc(Arc a) {
420 changeTarget(a,source(a));
424 ///Contract two nodes.
426 ///This function contracts the given two nodes.
427 ///Node \c v is removed, but instead of deleting its
428 ///incident arcs, they are joined to node \c u.
429 ///If the last parameter \c r is \c true (this is the default value),
430 ///then the newly created loops are removed.
432 ///\note The moved arcs are joined to node \c u using changeSource()
433 ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
434 ///invalidated for the outgoing arcs of node \c v and \c InArcIt
435 ///iterators are invalidated for the incomming arcs of \c v.
436 ///Moreover all iterators referencing node \c v or the removed
437 ///loops are also invalidated. Other iterators remain valid.
439 ///\warning This functionality cannot be used together with the Snapshot
441 void contract(Node u, Node v, bool r = true)
443 for(OutArcIt e(*this,v);e!=INVALID;) {
446 if(r && target(e)==u) erase(e);
447 else changeSource(e,u);
450 for(InArcIt e(*this,v);e!=INVALID;) {
453 if(r && source(e)==u) erase(e);
454 else changeTarget(e,u);
462 ///This function splits the given node. First, a new node is added
463 ///to the digraph, then the source of each outgoing arc of node \c n
464 ///is moved to this new node.
465 ///If the second parameter \c connect is \c true (this is the default
466 ///value), then a new arc from node \c n to the newly created node
468 ///\return The newly created node.
470 ///\note \c ArcIt and \c OutArcIt iterators referencing the outgoing
471 ///arcs of node \c n are invalidated. Other iterators remain valid.
473 ///\warning This functionality cannot be used together with the
475 Node split(Node n, bool connect = true) {
477 for(OutArcIt e(*this,n);e!=INVALID;) {
483 if (connect) addArc(n,b);
489 ///This function splits the given arc. First, a new node \c v is
490 ///added to the digraph, then the target node of the original arc
491 ///is set to \c v. Finally, an arc from \c v to the original target
493 ///\return The newly created node.
495 ///\note \c InArcIt iterators referencing the original arc are
496 ///invalidated. Other iterators remain valid.
498 ///\warning This functionality cannot be used together with the
507 ///Clear the digraph.
509 ///This function erases all nodes and arcs from the digraph.
515 /// Reserve memory for nodes.
517 /// Using this function, it is possible to avoid superfluous memory
518 /// allocation: if you know that the digraph you want to build will
519 /// be large (e.g. it will contain millions of nodes and/or arcs),
520 /// then it is worth reserving space for this amount before starting
521 /// to build the digraph.
523 void reserveNode(int n) { nodes.reserve(n); };
525 /// Reserve memory for arcs.
527 /// Using this function, it is possible to avoid superfluous memory
528 /// allocation: if you know that the digraph you want to build will
529 /// be large (e.g. it will contain millions of nodes and/or arcs),
530 /// then it is worth reserving space for this amount before starting
531 /// to build the digraph.
532 /// \sa reserveNode()
533 void reserveArc(int m) { arcs.reserve(m); };
535 /// \brief Class to make a snapshot of the digraph and restore
538 /// Class to make a snapshot of the digraph and restore it later.
540 /// The newly added nodes and arcs can be removed using the
541 /// restore() function.
543 /// \note After a state is restored, you cannot restore a later state,
544 /// i.e. you cannot add the removed nodes and arcs again using
545 /// another Snapshot instance.
547 /// \warning Node and arc deletions and other modifications (e.g.
548 /// reversing, contracting, splitting arcs or nodes) cannot be
549 /// restored. These events invalidate the snapshot.
550 /// However the arcs and nodes that were added to the digraph after
551 /// making the current snapshot can be removed without invalidating it.
555 typedef Parent::NodeNotifier NodeNotifier;
557 class NodeObserverProxy : public NodeNotifier::ObserverBase {
560 NodeObserverProxy(Snapshot& _snapshot)
561 : snapshot(_snapshot) {}
563 using NodeNotifier::ObserverBase::attach;
564 using NodeNotifier::ObserverBase::detach;
565 using NodeNotifier::ObserverBase::attached;
569 virtual void add(const Node& node) {
570 snapshot.addNode(node);
572 virtual void add(const std::vector<Node>& nodes) {
573 for (int i = nodes.size() - 1; i >= 0; ++i) {
574 snapshot.addNode(nodes[i]);
577 virtual void erase(const Node& node) {
578 snapshot.eraseNode(node);
580 virtual void erase(const std::vector<Node>& nodes) {
581 for (int i = 0; i < int(nodes.size()); ++i) {
582 snapshot.eraseNode(nodes[i]);
585 virtual void build() {
587 std::vector<Node> nodes;
588 for (notifier()->first(node); node != INVALID;
589 notifier()->next(node)) {
590 nodes.push_back(node);
592 for (int i = nodes.size() - 1; i >= 0; --i) {
593 snapshot.addNode(nodes[i]);
596 virtual void clear() {
598 for (notifier()->first(node); node != INVALID;
599 notifier()->next(node)) {
600 snapshot.eraseNode(node);
607 class ArcObserverProxy : public ArcNotifier::ObserverBase {
610 ArcObserverProxy(Snapshot& _snapshot)
611 : snapshot(_snapshot) {}
613 using ArcNotifier::ObserverBase::attach;
614 using ArcNotifier::ObserverBase::detach;
615 using ArcNotifier::ObserverBase::attached;
619 virtual void add(const Arc& arc) {
620 snapshot.addArc(arc);
622 virtual void add(const std::vector<Arc>& arcs) {
623 for (int i = arcs.size() - 1; i >= 0; ++i) {
624 snapshot.addArc(arcs[i]);
627 virtual void erase(const Arc& arc) {
628 snapshot.eraseArc(arc);
630 virtual void erase(const std::vector<Arc>& arcs) {
631 for (int i = 0; i < int(arcs.size()); ++i) {
632 snapshot.eraseArc(arcs[i]);
635 virtual void build() {
637 std::vector<Arc> arcs;
638 for (notifier()->first(arc); arc != INVALID;
639 notifier()->next(arc)) {
642 for (int i = arcs.size() - 1; i >= 0; --i) {
643 snapshot.addArc(arcs[i]);
646 virtual void clear() {
648 for (notifier()->first(arc); arc != INVALID;
649 notifier()->next(arc)) {
650 snapshot.eraseArc(arc);
657 ListDigraph *digraph;
659 NodeObserverProxy node_observer_proxy;
660 ArcObserverProxy arc_observer_proxy;
662 std::list<Node> added_nodes;
663 std::list<Arc> added_arcs;
666 void addNode(const Node& node) {
667 added_nodes.push_front(node);
669 void eraseNode(const Node& node) {
670 std::list<Node>::iterator it =
671 std::find(added_nodes.begin(), added_nodes.end(), node);
672 if (it == added_nodes.end()) {
674 arc_observer_proxy.detach();
675 throw NodeNotifier::ImmediateDetach();
677 added_nodes.erase(it);
681 void addArc(const Arc& arc) {
682 added_arcs.push_front(arc);
684 void eraseArc(const Arc& arc) {
685 std::list<Arc>::iterator it =
686 std::find(added_arcs.begin(), added_arcs.end(), arc);
687 if (it == added_arcs.end()) {
689 node_observer_proxy.detach();
690 throw ArcNotifier::ImmediateDetach();
692 added_arcs.erase(it);
696 void attach(ListDigraph &_digraph) {
698 node_observer_proxy.attach(digraph->notifier(Node()));
699 arc_observer_proxy.attach(digraph->notifier(Arc()));
703 node_observer_proxy.detach();
704 arc_observer_proxy.detach();
707 bool attached() const {
708 return node_observer_proxy.attached();
718 /// \brief Default constructor.
720 /// Default constructor.
721 /// You have to call save() to actually make a snapshot.
723 : digraph(0), node_observer_proxy(*this),
724 arc_observer_proxy(*this) {}
726 /// \brief Constructor that immediately makes a snapshot.
728 /// This constructor immediately makes a snapshot of the given digraph.
729 Snapshot(ListDigraph &gr)
730 : node_observer_proxy(*this),
731 arc_observer_proxy(*this) {
735 /// \brief Make a snapshot.
737 /// This function makes a snapshot of the given digraph.
738 /// It can be called more than once. In case of a repeated
739 /// call, the previous snapshot gets lost.
740 void save(ListDigraph &gr) {
748 /// \brief Undo the changes until the last snapshot.
750 /// This function undos the changes until the last snapshot
751 /// created by save() or Snapshot(ListDigraph&).
754 for(std::list<Arc>::iterator it = added_arcs.begin();
755 it != added_arcs.end(); ++it) {
758 for(std::list<Node>::iterator it = added_nodes.begin();
759 it != added_nodes.end(); ++it) {
765 /// \brief Returns \c true if the snapshot is valid.
767 /// This function returns \c true if the snapshot is valid.
777 class ListGraphBase {
788 int prev_out, next_out;
791 std::vector<NodeT> nodes;
797 std::vector<ArcT> arcs;
803 typedef ListGraphBase Graph;
806 friend class ListGraphBase;
810 explicit Node(int pid) { id = pid;}
814 Node (Invalid) { id = -1; }
815 bool operator==(const Node& node) const {return id == node.id;}
816 bool operator!=(const Node& node) const {return id != node.id;}
817 bool operator<(const Node& node) const {return id < node.id;}
821 friend class ListGraphBase;
825 explicit Edge(int pid) { id = pid;}
829 Edge (Invalid) { id = -1; }
830 bool operator==(const Edge& edge) const {return id == edge.id;}
831 bool operator!=(const Edge& edge) const {return id != edge.id;}
832 bool operator<(const Edge& edge) const {return id < edge.id;}
836 friend class ListGraphBase;
840 explicit Arc(int pid) { id = pid;}
843 operator Edge() const {
844 return id != -1 ? edgeFromId(id / 2) : INVALID;
848 Arc (Invalid) { id = -1; }
849 bool operator==(const Arc& arc) const {return id == arc.id;}
850 bool operator!=(const Arc& arc) const {return id != arc.id;}
851 bool operator<(const Arc& arc) const {return id < arc.id;}
855 : nodes(), first_node(-1),
856 first_free_node(-1), arcs(), first_free_arc(-1) {}
859 int maxNodeId() const { return nodes.size()-1; }
860 int maxEdgeId() const { return arcs.size() / 2 - 1; }
861 int maxArcId() const { return arcs.size()-1; }
863 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
864 Node target(Arc e) const { return Node(arcs[e.id].target); }
866 Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
867 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
869 static bool direction(Arc e) {
870 return (e.id & 1) == 1;
873 static Arc direct(Edge e, bool d) {
874 return Arc(e.id * 2 + (d ? 1 : 0));
877 void first(Node& node) const {
878 node.id = first_node;
881 void next(Node& node) const {
882 node.id = nodes[node.id].next;
885 void first(Arc& e) const {
887 while (n != -1 && nodes[n].first_out == -1) {
890 e.id = (n == -1) ? -1 : nodes[n].first_out;
893 void next(Arc& e) const {
894 if (arcs[e.id].next_out != -1) {
895 e.id = arcs[e.id].next_out;
897 int n = nodes[arcs[e.id ^ 1].target].next;
898 while(n != -1 && nodes[n].first_out == -1) {
901 e.id = (n == -1) ? -1 : nodes[n].first_out;
905 void first(Edge& e) const {
908 e.id = nodes[n].first_out;
909 while ((e.id & 1) != 1) {
910 e.id = arcs[e.id].next_out;
921 void next(Edge& e) const {
922 int n = arcs[e.id * 2].target;
923 e.id = arcs[(e.id * 2) | 1].next_out;
924 while ((e.id & 1) != 1) {
925 e.id = arcs[e.id].next_out;
933 e.id = nodes[n].first_out;
934 while ((e.id & 1) != 1) {
935 e.id = arcs[e.id].next_out;
946 void firstOut(Arc &e, const Node& v) const {
947 e.id = nodes[v.id].first_out;
949 void nextOut(Arc &e) const {
950 e.id = arcs[e.id].next_out;
953 void firstIn(Arc &e, const Node& v) const {
954 e.id = ((nodes[v.id].first_out) ^ 1);
955 if (e.id == -2) e.id = -1;
957 void nextIn(Arc &e) const {
958 e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
959 if (e.id == -2) e.id = -1;
962 void firstInc(Edge &e, bool& d, const Node& v) const {
963 int a = nodes[v.id].first_out;
972 void nextInc(Edge &e, bool& d) const {
973 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
983 static int id(Node v) { return v.id; }
984 static int id(Arc e) { return e.id; }
985 static int id(Edge e) { return e.id; }
987 static Node nodeFromId(int id) { return Node(id);}
988 static Arc arcFromId(int id) { return Arc(id);}
989 static Edge edgeFromId(int id) { return Edge(id);}
991 bool valid(Node n) const {
992 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
993 nodes[n.id].prev != -2;
996 bool valid(Arc a) const {
997 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
998 arcs[a.id].prev_out != -2;
1001 bool valid(Edge e) const {
1002 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1003 arcs[2 * e.id].prev_out != -2;
1009 if(first_free_node==-1) {
1011 nodes.push_back(NodeT());
1013 n = first_free_node;
1014 first_free_node = nodes[n].next;
1017 nodes[n].next = first_node;
1018 if (first_node != -1) nodes[first_node].prev = n;
1022 nodes[n].first_out = -1;
1027 Edge addEdge(Node u, Node v) {
1030 if (first_free_arc == -1) {
1032 arcs.push_back(ArcT());
1033 arcs.push_back(ArcT());
1036 first_free_arc = arcs[n].next_out;
1039 arcs[n].target = u.id;
1040 arcs[n | 1].target = v.id;
1042 arcs[n].next_out = nodes[v.id].first_out;
1043 if (nodes[v.id].first_out != -1) {
1044 arcs[nodes[v.id].first_out].prev_out = n;
1046 arcs[n].prev_out = -1;
1047 nodes[v.id].first_out = n;
1049 arcs[n | 1].next_out = nodes[u.id].first_out;
1050 if (nodes[u.id].first_out != -1) {
1051 arcs[nodes[u.id].first_out].prev_out = (n | 1);
1053 arcs[n | 1].prev_out = -1;
1054 nodes[u.id].first_out = (n | 1);
1059 void erase(const Node& node) {
1062 if(nodes[n].next != -1) {
1063 nodes[nodes[n].next].prev = nodes[n].prev;
1066 if(nodes[n].prev != -1) {
1067 nodes[nodes[n].prev].next = nodes[n].next;
1069 first_node = nodes[n].next;
1072 nodes[n].next = first_free_node;
1073 first_free_node = n;
1077 void erase(const Edge& edge) {
1078 int n = edge.id * 2;
1080 if (arcs[n].next_out != -1) {
1081 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1084 if (arcs[n].prev_out != -1) {
1085 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1087 nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1090 if (arcs[n | 1].next_out != -1) {
1091 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1094 if (arcs[n | 1].prev_out != -1) {
1095 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1097 nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1100 arcs[n].next_out = first_free_arc;
1102 arcs[n].prev_out = -2;
1103 arcs[n | 1].prev_out = -2;
1110 first_node = first_free_node = first_free_arc = -1;
1115 void changeV(Edge e, Node n) {
1116 if(arcs[2 * e.id].next_out != -1) {
1117 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1119 if(arcs[2 * e.id].prev_out != -1) {
1120 arcs[arcs[2 * e.id].prev_out].next_out =
1121 arcs[2 * e.id].next_out;
1123 nodes[arcs[(2 * e.id) | 1].target].first_out =
1124 arcs[2 * e.id].next_out;
1127 if (nodes[n.id].first_out != -1) {
1128 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1130 arcs[(2 * e.id) | 1].target = n.id;
1131 arcs[2 * e.id].prev_out = -1;
1132 arcs[2 * e.id].next_out = nodes[n.id].first_out;
1133 nodes[n.id].first_out = 2 * e.id;
1136 void changeU(Edge e, Node n) {
1137 if(arcs[(2 * e.id) | 1].next_out != -1) {
1138 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1139 arcs[(2 * e.id) | 1].prev_out;
1141 if(arcs[(2 * e.id) | 1].prev_out != -1) {
1142 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1143 arcs[(2 * e.id) | 1].next_out;
1145 nodes[arcs[2 * e.id].target].first_out =
1146 arcs[(2 * e.id) | 1].next_out;
1149 if (nodes[n.id].first_out != -1) {
1150 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1152 arcs[2 * e.id].target = n.id;
1153 arcs[(2 * e.id) | 1].prev_out = -1;
1154 arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1155 nodes[n.id].first_out = ((2 * e.id) | 1);
1160 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1163 /// \addtogroup graphs
1166 ///A general undirected graph structure.
1168 ///\ref ListGraph is a versatile and fast undirected graph
1169 ///implementation based on linked lists that are stored in
1170 ///\c std::vector structures.
1172 ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1173 ///and it also provides several useful additional functionalities.
1174 ///Most of its member functions and nested classes are documented
1175 ///only in the concept class.
1177 ///\sa concepts::Graph
1179 class ListGraph : public ExtendedListGraphBase {
1180 typedef ExtendedListGraphBase Parent;
1183 /// Graphs are \e not copy constructible. Use GraphCopy instead.
1184 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
1185 /// \brief Assignment of a graph to another one is \e not allowed.
1186 /// Use GraphCopy instead.
1187 void operator=(const ListGraph &) {}
1195 typedef Parent::OutArcIt IncEdgeIt;
1197 /// \brief Add a new node to the graph.
1199 /// This function adds a new node to the graph.
1200 /// \return The new node.
1201 Node addNode() { return Parent::addNode(); }
1203 /// \brief Add a new edge to the graph.
1205 /// This function adds a new edge to the graph between nodes
1206 /// \c u and \c v with inherent orientation from node \c u to
1208 /// \return The new edge.
1209 Edge addEdge(Node u, Node v) {
1210 return Parent::addEdge(u, v);
1213 ///\brief Erase a node from the graph.
1215 /// This function erases the given node from the graph.
1216 void erase(Node n) { Parent::erase(n); }
1218 ///\brief Erase an edge from the graph.
1220 /// This function erases the given edge from the graph.
1221 void erase(Edge e) { Parent::erase(e); }
1222 /// Node validity check
1224 /// This function gives back \c true if the given node is valid,
1225 /// i.e. it is a real node of the graph.
1227 /// \warning A removed node could become valid again if new nodes are
1228 /// added to the graph.
1229 bool valid(Node n) const { return Parent::valid(n); }
1230 /// Edge validity check
1232 /// This function gives back \c true if the given edge is valid,
1233 /// i.e. it is a real edge of the graph.
1235 /// \warning A removed edge could become valid again if new edges are
1236 /// added to the graph.
1237 bool valid(Edge e) const { return Parent::valid(e); }
1238 /// Arc validity check
1240 /// This function gives back \c true if the given arc is valid,
1241 /// i.e. it is a real arc of the graph.
1243 /// \warning A removed arc could become valid again if new edges are
1244 /// added to the graph.
1245 bool valid(Arc a) const { return Parent::valid(a); }
1247 /// \brief Change the first node of an edge.
1249 /// This function changes the first node of the given edge \c e to \c n.
1251 ///\note \c EdgeIt and \c ArcIt iterators referencing the
1252 ///changed edge are invalidated and all other iterators whose
1253 ///base node is the changed node are also invalidated.
1255 ///\warning This functionality cannot be used together with the
1256 ///Snapshot feature.
1257 void changeU(Edge e, Node n) {
1258 Parent::changeU(e,n);
1260 /// \brief Change the second node of an edge.
1262 /// This function changes the second node of the given edge \c e to \c n.
1264 ///\note \c EdgeIt iterators referencing the changed edge remain
1265 ///valid, however \c ArcIt iterators referencing the changed edge and
1266 ///all other iterators whose base node is the changed node are also
1269 ///\warning This functionality cannot be used together with the
1270 ///Snapshot feature.
1271 void changeV(Edge e, Node n) {
1272 Parent::changeV(e,n);
1275 /// \brief Contract two nodes.
1277 /// This function contracts the given two nodes.
1278 /// Node \c b is removed, but instead of deleting
1279 /// its incident edges, they are joined to node \c a.
1280 /// If the last parameter \c r is \c true (this is the default value),
1281 /// then the newly created loops are removed.
1283 /// \note The moved edges are joined to node \c a using changeU()
1284 /// or changeV(), thus all edge and arc iterators whose base node is
1285 /// \c b are invalidated.
1286 /// Moreover all iterators referencing node \c b or the removed
1287 /// loops are also invalidated. Other iterators remain valid.
1289 ///\warning This functionality cannot be used together with the
1290 ///Snapshot feature.
1291 void contract(Node a, Node b, bool r = true) {
1292 for(IncEdgeIt e(*this, b); e!=INVALID;) {
1293 IncEdgeIt f = e; ++f;
1294 if (r && runningNode(e) == a) {
1296 } else if (u(e) == b) {
1308 ///This function erases all nodes and arcs from the graph.
1314 /// Reserve memory for nodes.
1316 /// Using this function, it is possible to avoid superfluous memory
1317 /// allocation: if you know that the graph you want to build will
1318 /// be large (e.g. it will contain millions of nodes and/or edges),
1319 /// then it is worth reserving space for this amount before starting
1320 /// to build the graph.
1321 /// \sa reserveEdge()
1322 void reserveNode(int n) { nodes.reserve(n); };
1324 /// Reserve memory for edges.
1326 /// Using this function, it is possible to avoid superfluous memory
1327 /// allocation: if you know that the graph you want to build will
1328 /// be large (e.g. it will contain millions of nodes and/or edges),
1329 /// then it is worth reserving space for this amount before starting
1330 /// to build the graph.
1331 /// \sa reserveNode()
1332 void reserveEdge(int m) { arcs.reserve(2 * m); };
1334 /// \brief Class to make a snapshot of the graph and restore
1337 /// Class to make a snapshot of the graph and restore it later.
1339 /// The newly added nodes and edges can be removed
1340 /// using the restore() function.
1342 /// \note After a state is restored, you cannot restore a later state,
1343 /// i.e. you cannot add the removed nodes and edges again using
1344 /// another Snapshot instance.
1346 /// \warning Node and edge deletions and other modifications
1347 /// (e.g. changing the end-nodes of edges or contracting nodes)
1348 /// cannot be restored. These events invalidate the snapshot.
1349 /// However the edges and nodes that were added to the graph after
1350 /// making the current snapshot can be removed without invalidating it.
1354 typedef Parent::NodeNotifier NodeNotifier;
1356 class NodeObserverProxy : public NodeNotifier::ObserverBase {
1359 NodeObserverProxy(Snapshot& _snapshot)
1360 : snapshot(_snapshot) {}
1362 using NodeNotifier::ObserverBase::attach;
1363 using NodeNotifier::ObserverBase::detach;
1364 using NodeNotifier::ObserverBase::attached;
1368 virtual void add(const Node& node) {
1369 snapshot.addNode(node);
1371 virtual void add(const std::vector<Node>& nodes) {
1372 for (int i = nodes.size() - 1; i >= 0; ++i) {
1373 snapshot.addNode(nodes[i]);
1376 virtual void erase(const Node& node) {
1377 snapshot.eraseNode(node);
1379 virtual void erase(const std::vector<Node>& nodes) {
1380 for (int i = 0; i < int(nodes.size()); ++i) {
1381 snapshot.eraseNode(nodes[i]);
1384 virtual void build() {
1386 std::vector<Node> nodes;
1387 for (notifier()->first(node); node != INVALID;
1388 notifier()->next(node)) {
1389 nodes.push_back(node);
1391 for (int i = nodes.size() - 1; i >= 0; --i) {
1392 snapshot.addNode(nodes[i]);
1395 virtual void clear() {
1397 for (notifier()->first(node); node != INVALID;
1398 notifier()->next(node)) {
1399 snapshot.eraseNode(node);
1406 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1409 EdgeObserverProxy(Snapshot& _snapshot)
1410 : snapshot(_snapshot) {}
1412 using EdgeNotifier::ObserverBase::attach;
1413 using EdgeNotifier::ObserverBase::detach;
1414 using EdgeNotifier::ObserverBase::attached;
1418 virtual void add(const Edge& edge) {
1419 snapshot.addEdge(edge);
1421 virtual void add(const std::vector<Edge>& edges) {
1422 for (int i = edges.size() - 1; i >= 0; ++i) {
1423 snapshot.addEdge(edges[i]);
1426 virtual void erase(const Edge& edge) {
1427 snapshot.eraseEdge(edge);
1429 virtual void erase(const std::vector<Edge>& edges) {
1430 for (int i = 0; i < int(edges.size()); ++i) {
1431 snapshot.eraseEdge(edges[i]);
1434 virtual void build() {
1436 std::vector<Edge> edges;
1437 for (notifier()->first(edge); edge != INVALID;
1438 notifier()->next(edge)) {
1439 edges.push_back(edge);
1441 for (int i = edges.size() - 1; i >= 0; --i) {
1442 snapshot.addEdge(edges[i]);
1445 virtual void clear() {
1447 for (notifier()->first(edge); edge != INVALID;
1448 notifier()->next(edge)) {
1449 snapshot.eraseEdge(edge);
1458 NodeObserverProxy node_observer_proxy;
1459 EdgeObserverProxy edge_observer_proxy;
1461 std::list<Node> added_nodes;
1462 std::list<Edge> added_edges;
1465 void addNode(const Node& node) {
1466 added_nodes.push_front(node);
1468 void eraseNode(const Node& node) {
1469 std::list<Node>::iterator it =
1470 std::find(added_nodes.begin(), added_nodes.end(), node);
1471 if (it == added_nodes.end()) {
1473 edge_observer_proxy.detach();
1474 throw NodeNotifier::ImmediateDetach();
1476 added_nodes.erase(it);
1480 void addEdge(const Edge& edge) {
1481 added_edges.push_front(edge);
1483 void eraseEdge(const Edge& edge) {
1484 std::list<Edge>::iterator it =
1485 std::find(added_edges.begin(), added_edges.end(), edge);
1486 if (it == added_edges.end()) {
1488 node_observer_proxy.detach();
1489 throw EdgeNotifier::ImmediateDetach();
1491 added_edges.erase(it);
1495 void attach(ListGraph &_graph) {
1497 node_observer_proxy.attach(graph->notifier(Node()));
1498 edge_observer_proxy.attach(graph->notifier(Edge()));
1502 node_observer_proxy.detach();
1503 edge_observer_proxy.detach();
1506 bool attached() const {
1507 return node_observer_proxy.attached();
1511 added_nodes.clear();
1512 added_edges.clear();
1517 /// \brief Default constructor.
1519 /// Default constructor.
1520 /// You have to call save() to actually make a snapshot.
1522 : graph(0), node_observer_proxy(*this),
1523 edge_observer_proxy(*this) {}
1525 /// \brief Constructor that immediately makes a snapshot.
1527 /// This constructor immediately makes a snapshot of the given graph.
1528 Snapshot(ListGraph &gr)
1529 : node_observer_proxy(*this),
1530 edge_observer_proxy(*this) {
1534 /// \brief Make a snapshot.
1536 /// This function makes a snapshot of the given graph.
1537 /// It can be called more than once. In case of a repeated
1538 /// call, the previous snapshot gets lost.
1539 void save(ListGraph &gr) {
1547 /// \brief Undo the changes until the last snapshot.
1549 /// This function undos the changes until the last snapshot
1550 /// created by save() or Snapshot(ListGraph&).
1553 for(std::list<Edge>::iterator it = added_edges.begin();
1554 it != added_edges.end(); ++it) {
1557 for(std::list<Node>::iterator it = added_nodes.begin();
1558 it != added_nodes.end(); ++it) {
1564 /// \brief Returns \c true if the snapshot is valid.
1566 /// This function returns \c true if the snapshot is valid.
1567 bool valid() const {