3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
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 ListGraph, ListUGraph classes.
26 #include <lemon/bits/base_extender.h>
27 #include <lemon/bits/graph_extender.h>
29 #include <lemon/error.h>
40 int first_in, first_out;
46 int prev_in, prev_out;
47 int next_in, next_out;
50 std::vector<NodeT> nodes;
56 std::vector<EdgeT> edges;
62 typedef ListGraphBase Graph;
65 friend class ListGraphBase;
69 explicit Node(int pid) { id = pid;}
73 Node (Invalid) { id = -1; }
74 bool operator==(const Node& node) const {return id == node.id;}
75 bool operator!=(const Node& node) const {return id != node.id;}
76 bool operator<(const Node& node) const {return id < node.id;}
80 friend class ListGraphBase;
84 explicit Edge(int pid) { id = pid;}
88 Edge (Invalid) { id = -1; }
89 bool operator==(const Edge& edge) const {return id == edge.id;}
90 bool operator!=(const Edge& edge) const {return id != edge.id;}
91 bool operator<(const Edge& edge) const {return id < edge.id;}
97 : nodes(), first_node(-1),
98 first_free_node(-1), edges(), first_free_edge(-1) {}
101 int maxNodeId() const { return nodes.size()-1; }
102 int maxEdgeId() const { return edges.size()-1; }
104 Node source(Edge e) const { return Node(edges[e.id].source); }
105 Node target(Edge e) const { return Node(edges[e.id].target); }
108 void first(Node& node) const {
109 node.id = first_node;
112 void next(Node& node) const {
113 node.id = nodes[node.id].next;
117 void first(Edge& e) const {
120 n!=-1 && nodes[n].first_in == -1;
122 e.id = (n == -1) ? -1 : nodes[n].first_in;
125 void next(Edge& edge) const {
126 if (edges[edge.id].next_in != -1) {
127 edge.id = edges[edge.id].next_in;
130 for(n = nodes[edges[edge.id].target].next;
131 n!=-1 && nodes[n].first_in == -1;
133 edge.id = (n == -1) ? -1 : nodes[n].first_in;
137 void firstOut(Edge &e, const Node& v) const {
138 e.id = nodes[v.id].first_out;
140 void nextOut(Edge &e) const {
141 e.id=edges[e.id].next_out;
144 void firstIn(Edge &e, const Node& v) const {
145 e.id = nodes[v.id].first_in;
147 void nextIn(Edge &e) const {
148 e.id=edges[e.id].next_in;
152 static int id(Node v) { return v.id; }
153 static int id(Edge e) { return e.id; }
155 static Node nodeFromId(int id) { return Node(id);}
156 static Edge edgeFromId(int id) { return Edge(id);}
161 if(first_free_node==-1) {
163 nodes.push_back(NodeT());
166 first_free_node = nodes[n].next;
169 nodes[n].next = first_node;
170 if(first_node != -1) nodes[first_node].prev = n;
174 nodes[n].first_in = nodes[n].first_out = -1;
179 Edge addEdge(Node u, Node v) {
182 if (first_free_edge == -1) {
184 edges.push_back(EdgeT());
187 first_free_edge = edges[n].next_in;
190 edges[n].source = u.id;
191 edges[n].target = v.id;
193 edges[n].next_out = nodes[u.id].first_out;
194 if(nodes[u.id].first_out != -1) {
195 edges[nodes[u.id].first_out].prev_out = n;
198 edges[n].next_in = nodes[v.id].first_in;
199 if(nodes[v.id].first_in != -1) {
200 edges[nodes[v.id].first_in].prev_in = n;
203 edges[n].prev_in = edges[n].prev_out = -1;
205 nodes[u.id].first_out = nodes[v.id].first_in = n;
210 void erase(const Node& node) {
213 if(nodes[n].next != -1) {
214 nodes[nodes[n].next].prev = nodes[n].prev;
217 if(nodes[n].prev != -1) {
218 nodes[nodes[n].prev].next = nodes[n].next;
220 first_node = nodes[n].next;
223 nodes[n].next = first_free_node;
228 void erase(const Edge& edge) {
231 if(edges[n].next_in!=-1) {
232 edges[edges[n].next_in].prev_in = edges[n].prev_in;
235 if(edges[n].prev_in!=-1) {
236 edges[edges[n].prev_in].next_in = edges[n].next_in;
238 nodes[edges[n].target].first_in = edges[n].next_in;
242 if(edges[n].next_out!=-1) {
243 edges[edges[n].next_out].prev_out = edges[n].prev_out;
246 if(edges[n].prev_out!=-1) {
247 edges[edges[n].prev_out].next_out = edges[n].next_out;
249 nodes[edges[n].source].first_out = edges[n].next_out;
252 edges[n].next_in = first_free_edge;
260 first_node = first_free_node = first_free_edge = -1;
264 void changeTarget(Edge e, Node n)
266 if(edges[e.id].next_in != -1)
267 edges[edges[e.id].next_in].prev_in = edges[e.id].prev_in;
268 if(edges[e.id].prev_in != -1)
269 edges[edges[e.id].prev_in].next_in = edges[e.id].next_in;
270 else nodes[edges[e.id].target].first_in = edges[e.id].next_in;
271 if (nodes[n.id].first_in != -1) {
272 edges[nodes[n.id].first_in].prev_in = e.id;
274 edges[e.id].target = n.id;
275 edges[e.id].prev_in = -1;
276 edges[e.id].next_in = nodes[n.id].first_in;
277 nodes[n.id].first_in = e.id;
279 void changeSource(Edge e, Node n)
281 if(edges[e.id].next_out != -1)
282 edges[edges[e.id].next_out].prev_out = edges[e.id].prev_out;
283 if(edges[e.id].prev_out != -1)
284 edges[edges[e.id].prev_out].next_out = edges[e.id].next_out;
285 else nodes[edges[e.id].source].first_out = edges[e.id].next_out;
286 if (nodes[n.id].first_out != -1) {
287 edges[nodes[n.id].first_out].prev_out = e.id;
289 edges[e.id].source = n.id;
290 edges[e.id].prev_out = -1;
291 edges[e.id].next_out = nodes[n.id].first_out;
292 nodes[n.id].first_out = e.id;
297 typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
299 /// \addtogroup graphs
302 ///A list graph class.
304 ///This is a simple and fast graph implementation.
306 ///It conforms to the \ref concepts::Graph "Graph concept" and it
307 ///also provides several additional useful extra functionalities.
308 ///The most of the member functions and nested classes are
309 ///documented only in the concept class.
311 ///An important extra feature of this graph implementation is that
312 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
314 ///\sa concepts::Graph.
316 class ListGraph : public ExtendedListGraphBase {
318 ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
320 ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
322 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
323 ///\brief Assignment of ListGraph to another one is \e not allowed.
324 ///Use GraphCopy() instead.
326 ///Assignment of ListGraph to another one is \e not allowed.
327 ///Use GraphCopy() instead.
328 void operator=(const ListGraph &) {}
331 typedef ExtendedListGraphBase Parent;
339 ///Add a new node to the graph.
341 /// \return the new node.
343 Node addNode() { return Parent::addNode(); }
345 ///Add a new edge to the graph.
347 ///Add a new edge to the graph with source node \c s
348 ///and target node \c t.
349 ///\return the new edge.
350 Edge addEdge(const Node& s, const Node& t) {
351 return Parent::addEdge(s, t);
354 /// Changes the target of \c e to \c n
356 /// Changes the target of \c e to \c n
358 ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s referencing
359 ///the changed edge remain valid. However <tt>InEdgeIt</tt>s are
361 ///\warning This functionality cannot be used together with the Snapshot
363 void changeTarget(Edge e, Node n) {
364 Parent::changeTarget(e,n);
366 /// Changes the source of \c e to \c n
368 /// Changes the source of \c e to \c n
370 ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
371 ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
373 ///\warning This functionality cannot be used together with the Snapshot
375 void changeSource(Edge e, Node n) {
376 Parent::changeSource(e,n);
379 /// Invert the direction of an edge.
381 ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
382 ///valid. However <tt>OutEdgeIt</tt>s and <tt>InEdgeIt</tt>s are
384 ///\warning This functionality cannot be used together with the Snapshot
386 void reverseEdge(Edge e) {
388 changeTarget(e,source(e));
392 /// \brief Using this it is possible to avoid the superfluous memory
395 ///Using this it is possible to avoid the superfluous memory
396 ///allocation: if you know that the graph you want to build will
397 ///contain at least 10 million nodes then it is worth reserving
398 ///space for this amount before starting to build the graph.
399 void reserveNode(int n) { nodes.reserve(n); };
401 /// \brief Using this it is possible to avoid the superfluous memory
404 ///Using this it is possible to avoid the superfluous memory
405 ///allocation: see the \ref reserveNode function.
406 void reserveEdge(int n) { edges.reserve(n); };
409 ///Contract two nodes.
411 ///This function contracts two nodes.
413 ///Node \p b will be removed but instead of deleting
414 ///incident edges, they will be joined to \p a.
415 ///The last parameter \p r controls whether to remove loops. \c true
416 ///means that loops will be removed.
418 ///\note The <tt>EdgeIt</tt>s
419 ///referencing a moved edge remain
420 ///valid. However <tt>InEdgeIt</tt>s and <tt>OutEdgeIt</tt>s
421 ///may be invalidated.
422 ///\warning This functionality cannot be used together with the Snapshot
424 void contract(Node a, Node b, bool r = true)
426 for(OutEdgeIt e(*this,b);e!=INVALID;) {
429 if(r && target(e)==a) erase(e);
430 else changeSource(e,a);
433 for(InEdgeIt e(*this,b);e!=INVALID;) {
436 if(r && source(e)==a) erase(e);
437 else changeTarget(e,a);
445 ///This function splits a node. First a new node is added to the graph,
446 ///then the source of each outgoing edge of \c n is moved to this new node.
447 ///If \c connect is \c true (this is the default value), then a new edge
448 ///from \c n to the newly created node is also added.
449 ///\return The newly created node.
451 ///\note The <tt>EdgeIt</tt>s referencing a moved edge remain
452 ///valid. However <tt>InEdgeIt</tt>s and <tt>OutEdgeIt</tt>s may
455 ///\warning This functionality cannot be used together with the
456 ///Snapshot feature. \todo It could be implemented in a bit
458 Node split(Node n, bool connect = true) {
460 for(OutEdgeIt e(*this,n);e!=INVALID;) {
466 if (connect) addEdge(n,b);
472 ///This function splits an edge. First a new node \c b is added to
473 ///the graph, then the original edge is re-targeted to \c
474 ///b. Finally an edge from \c b to the original target is added.
475 ///\return The newly created node.
476 ///\warning This functionality
477 ///cannot be used together with the Snapshot feature.
480 addEdge(b,target(e));
485 /// \brief Class to make a snapshot of the graph and restore
488 /// Class to make a snapshot of the graph and to restore it
491 /// The newly added nodes and edges can be removed using the
492 /// restore() function.
494 /// \warning Edge and node deletions cannot be restored. This
495 /// events invalidate the snapshot.
499 typedef Parent::NodeNotifier NodeNotifier;
501 class NodeObserverProxy : public NodeNotifier::ObserverBase {
504 NodeObserverProxy(Snapshot& _snapshot)
505 : snapshot(_snapshot) {}
507 using NodeNotifier::ObserverBase::attach;
508 using NodeNotifier::ObserverBase::detach;
509 using NodeNotifier::ObserverBase::attached;
513 virtual void add(const Node& node) {
514 snapshot.addNode(node);
516 virtual void add(const std::vector<Node>& nodes) {
517 for (int i = nodes.size() - 1; i >= 0; ++i) {
518 snapshot.addNode(nodes[i]);
521 virtual void erase(const Node& node) {
522 snapshot.eraseNode(node);
524 virtual void erase(const std::vector<Node>& nodes) {
525 for (int i = 0; i < (int)nodes.size(); ++i) {
526 snapshot.eraseNode(nodes[i]);
529 virtual void build() {
530 NodeNotifier* _notifier = notifier();
532 std::vector<Node> nodes;
533 for (_notifier->first(node); node != INVALID;
534 _notifier->next(node)) {
535 nodes.push_back(node);
537 for (int i = nodes.size() - 1; i >= 0; --i) {
538 snapshot.addNode(nodes[i]);
541 virtual void clear() {
542 NodeNotifier* _notifier = notifier();
544 for (_notifier->first(node); node != INVALID;
545 _notifier->next(node)) {
546 snapshot.eraseNode(node);
553 class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
556 EdgeObserverProxy(Snapshot& _snapshot)
557 : snapshot(_snapshot) {}
559 using EdgeNotifier::ObserverBase::attach;
560 using EdgeNotifier::ObserverBase::detach;
561 using EdgeNotifier::ObserverBase::attached;
565 virtual void add(const Edge& edge) {
566 snapshot.addEdge(edge);
568 virtual void add(const std::vector<Edge>& edges) {
569 for (int i = edges.size() - 1; i >= 0; ++i) {
570 snapshot.addEdge(edges[i]);
573 virtual void erase(const Edge& edge) {
574 snapshot.eraseEdge(edge);
576 virtual void erase(const std::vector<Edge>& edges) {
577 for (int i = 0; i < (int)edges.size(); ++i) {
578 snapshot.eraseEdge(edges[i]);
581 virtual void build() {
582 EdgeNotifier* _notifier = notifier();
584 std::vector<Edge> edges;
585 for (_notifier->first(edge); edge != INVALID;
586 _notifier->next(edge)) {
587 edges.push_back(edge);
589 for (int i = edges.size() - 1; i >= 0; --i) {
590 snapshot.addEdge(edges[i]);
593 virtual void clear() {
594 EdgeNotifier* _notifier = notifier();
596 for (_notifier->first(edge); edge != INVALID; _notifier->next(edge)) {
597 snapshot.eraseEdge(edge);
606 NodeObserverProxy node_observer_proxy;
607 EdgeObserverProxy edge_observer_proxy;
609 std::list<Node> added_nodes;
610 std::list<Edge> added_edges;
613 void addNode(const Node& node) {
614 added_nodes.push_front(node);
616 void eraseNode(const Node& node) {
617 std::list<Node>::iterator it =
618 std::find(added_nodes.begin(), added_nodes.end(), node);
619 if (it == added_nodes.end()) {
621 edge_observer_proxy.detach();
622 throw NodeNotifier::ImmediateDetach();
624 added_nodes.erase(it);
628 void addEdge(const Edge& edge) {
629 added_edges.push_front(edge);
631 void eraseEdge(const Edge& edge) {
632 std::list<Edge>::iterator it =
633 std::find(added_edges.begin(), added_edges.end(), edge);
634 if (it == added_edges.end()) {
636 node_observer_proxy.detach();
637 throw EdgeNotifier::ImmediateDetach();
639 added_edges.erase(it);
643 void attach(ListGraph &_graph) {
645 node_observer_proxy.attach(graph->notifier(Node()));
646 edge_observer_proxy.attach(graph->notifier(Edge()));
650 node_observer_proxy.detach();
651 edge_observer_proxy.detach();
654 bool attached() const {
655 return node_observer_proxy.attached();
665 /// \brief Default constructor.
667 /// Default constructor.
668 /// To actually make a snapshot you must call save().
670 : graph(0), node_observer_proxy(*this),
671 edge_observer_proxy(*this) {}
673 /// \brief Constructor that immediately makes a snapshot.
675 /// This constructor immediately makes a snapshot of the graph.
676 /// \param _graph The graph we make a snapshot of.
677 Snapshot(ListGraph &_graph)
678 : node_observer_proxy(*this),
679 edge_observer_proxy(*this) {
683 /// \brief Make a snapshot.
685 /// Make a snapshot of the graph.
687 /// This function can be called more than once. In case of a repeated
688 /// call, the previous snapshot gets lost.
689 /// \param _graph The graph we make the snapshot of.
690 void save(ListGraph &_graph) {
698 /// \brief Undo the changes until the last snapshot.
700 /// Undo the changes until the last snapshot created by save().
703 for(std::list<Edge>::iterator it = added_edges.begin();
704 it != added_edges.end(); ++it) {
707 for(std::list<Node>::iterator it = added_nodes.begin();
708 it != added_nodes.end(); ++it) {
714 /// \brief Gives back true when the snapshot is valid.
716 /// Gives back true when the snapshot is valid.
726 class ListUGraphBase {
737 int prev_out, next_out;
740 std::vector<NodeT> nodes;
746 std::vector<EdgeT> edges;
752 typedef ListUGraphBase Graph;
759 friend class ListUGraphBase;
763 explicit Node(int pid) { id = pid;}
767 Node (Invalid) { id = -1; }
768 bool operator==(const Node& node) const {return id == node.id;}
769 bool operator!=(const Node& node) const {return id != node.id;}
770 bool operator<(const Node& node) const {return id < node.id;}
774 friend class ListUGraphBase;
778 explicit UEdge(int pid) { id = pid;}
782 UEdge (Invalid) { id = -1; }
783 bool operator==(const UEdge& edge) const {return id == edge.id;}
784 bool operator!=(const UEdge& edge) const {return id != edge.id;}
785 bool operator<(const UEdge& edge) const {return id < edge.id;}
789 friend class ListUGraphBase;
793 explicit Edge(int pid) { id = pid;}
796 operator UEdge() const { return uEdgeFromId(id / 2); }
799 Edge (Invalid) { id = -1; }
800 bool operator==(const Edge& edge) const {return id == edge.id;}
801 bool operator!=(const Edge& edge) const {return id != edge.id;}
802 bool operator<(const Edge& edge) const {return id < edge.id;}
808 : nodes(), first_node(-1),
809 first_free_node(-1), edges(), first_free_edge(-1) {}
812 int maxNodeId() const { return nodes.size()-1; }
813 int maxUEdgeId() const { return edges.size() / 2 - 1; }
814 int maxEdgeId() const { return edges.size()-1; }
816 Node source(Edge e) const { return Node(edges[e.id ^ 1].target); }
817 Node target(Edge e) const { return Node(edges[e.id].target); }
819 Node source(UEdge e) const { return Node(edges[2 * e.id].target); }
820 Node target(UEdge e) const { return Node(edges[2 * e.id + 1].target); }
822 static bool direction(Edge e) {
823 return (e.id & 1) == 1;
826 static Edge direct(UEdge e, bool d) {
827 return Edge(e.id * 2 + (d ? 1 : 0));
830 void first(Node& node) const {
831 node.id = first_node;
834 void next(Node& node) const {
835 node.id = nodes[node.id].next;
838 void first(Edge& e) const {
840 while (n != -1 && nodes[n].first_out == -1) {
843 e.id = (n == -1) ? -1 : nodes[n].first_out;
846 void next(Edge& e) const {
847 if (edges[e.id].next_out != -1) {
848 e.id = edges[e.id].next_out;
850 int n = nodes[edges[e.id ^ 1].target].next;
851 while(n != -1 && nodes[n].first_out == -1) {
854 e.id = (n == -1) ? -1 : nodes[n].first_out;
858 void first(UEdge& e) const {
861 e.id = nodes[n].first_out;
862 while ((e.id & 1) != 1) {
863 e.id = edges[e.id].next_out;
874 void next(UEdge& e) const {
875 int n = edges[e.id * 2].target;
876 e.id = edges[(e.id * 2) | 1].next_out;
877 while ((e.id & 1) != 1) {
878 e.id = edges[e.id].next_out;
886 e.id = nodes[n].first_out;
887 while ((e.id & 1) != 1) {
888 e.id = edges[e.id].next_out;
899 void firstOut(Edge &e, const Node& v) const {
900 e.id = nodes[v.id].first_out;
902 void nextOut(Edge &e) const {
903 e.id = edges[e.id].next_out;
906 void firstIn(Edge &e, const Node& v) const {
907 e.id = ((nodes[v.id].first_out) ^ 1);
908 if (e.id == -2) e.id = -1;
910 void nextIn(Edge &e) const {
911 e.id = ((edges[e.id ^ 1].next_out) ^ 1);
912 if (e.id == -2) e.id = -1;
915 void firstInc(UEdge &e, bool& d, const Node& v) const {
916 int de = nodes[v.id].first_out;
925 void nextInc(UEdge &e, bool& d) const {
926 int de = (edges[(e.id * 2) | (d ? 1 : 0)].next_out);
936 static int id(Node v) { return v.id; }
937 static int id(Edge e) { return e.id; }
938 static int id(UEdge e) { return e.id; }
940 static Node nodeFromId(int id) { return Node(id);}
941 static Edge edgeFromId(int id) { return Edge(id);}
942 static UEdge uEdgeFromId(int id) { return UEdge(id);}
947 if(first_free_node==-1) {
949 nodes.push_back(NodeT());
952 first_free_node = nodes[n].next;
955 nodes[n].next = first_node;
956 if (first_node != -1) nodes[first_node].prev = n;
960 nodes[n].first_out = -1;
965 UEdge addEdge(Node u, Node v) {
968 if (first_free_edge == -1) {
970 edges.push_back(EdgeT());
971 edges.push_back(EdgeT());
974 first_free_edge = edges[n].next_out;
977 edges[n].target = u.id;
978 edges[n | 1].target = v.id;
980 edges[n].next_out = nodes[v.id].first_out;
981 edges[n | 1].next_out = nodes[u.id].first_out;
982 if (nodes[v.id].first_out != -1) {
983 edges[nodes[v.id].first_out].prev_out = n;
985 if (nodes[u.id].first_out != -1) {
986 edges[nodes[u.id].first_out].prev_out = (n | 1);
989 edges[n].prev_out = edges[n | 1].prev_out = -1;
991 nodes[v.id].first_out = n;
992 nodes[u.id].first_out = (n | 1);
997 void erase(const Node& node) {
1000 if(nodes[n].next != -1) {
1001 nodes[nodes[n].next].prev = nodes[n].prev;
1004 if(nodes[n].prev != -1) {
1005 nodes[nodes[n].prev].next = nodes[n].next;
1007 first_node = nodes[n].next;
1010 nodes[n].next = first_free_node;
1011 first_free_node = n;
1015 void erase(const UEdge& edge) {
1016 int n = edge.id * 2;
1018 if (edges[n].next_out != -1) {
1019 edges[edges[n].next_out].prev_out = edges[n].prev_out;
1022 if (edges[n].prev_out != -1) {
1023 edges[edges[n].prev_out].next_out = edges[n].next_out;
1025 nodes[edges[n | 1].target].first_out = edges[n].next_out;
1028 if (edges[n | 1].next_out != -1) {
1029 edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
1032 if (edges[n | 1].prev_out != -1) {
1033 edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
1035 nodes[edges[n].target].first_out = edges[n | 1].next_out;
1038 edges[n].next_out = first_free_edge;
1039 first_free_edge = n;
1046 first_node = first_free_node = first_free_edge = -1;
1051 void changeTarget(UEdge e, Node n) {
1052 if(edges[2 * e.id].next_out != -1) {
1053 edges[edges[2 * e.id].next_out].prev_out = edges[2 * e.id].prev_out;
1055 if(edges[2 * e.id].prev_out != -1) {
1056 edges[edges[2 * e.id].prev_out].next_out =
1057 edges[2 * e.id].next_out;
1059 nodes[edges[(2 * e.id) | 1].target].first_out =
1060 edges[2 * e.id].next_out;
1063 if (nodes[n.id].first_out != -1) {
1064 edges[nodes[n.id].first_out].prev_out = 2 * e.id;
1066 edges[(2 * e.id) | 1].target = n.id;
1067 edges[2 * e.id].prev_out = -1;
1068 edges[2 * e.id].next_out = nodes[n.id].first_out;
1069 nodes[n.id].first_out = 2 * e.id;
1072 void changeSource(UEdge e, Node n) {
1073 if(edges[(2 * e.id) | 1].next_out != -1) {
1074 edges[edges[(2 * e.id) | 1].next_out].prev_out =
1075 edges[(2 * e.id) | 1].prev_out;
1077 if(edges[(2 * e.id) | 1].prev_out != -1) {
1078 edges[edges[(2 * e.id) | 1].prev_out].next_out =
1079 edges[(2 * e.id) | 1].next_out;
1081 nodes[edges[2 * e.id].target].first_out =
1082 edges[(2 * e.id) | 1].next_out;
1085 if (nodes[n.id].first_out != -1) {
1086 edges[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1088 edges[2 * e.id].target = n.id;
1089 edges[(2 * e.id) | 1].prev_out = -1;
1090 edges[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1091 nodes[n.id].first_out = ((2 * e.id) | 1);
1096 // typedef UGraphExtender<UndirGraphExtender<ListGraphBase> >
1097 // ExtendedListUGraphBase;
1099 typedef UGraphExtender<ListUGraphBase> ExtendedListUGraphBase;
1103 /// \addtogroup graphs
1106 ///An undirected list graph class.
1108 ///This is a simple and fast undirected graph implementation.
1110 ///An important extra feature of this graph implementation is that
1111 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1113 ///It conforms to the
1114 ///\ref concepts::UGraph "UGraph concept".
1116 ///\sa concepts::UGraph.
1118 class ListUGraph : public ExtendedListUGraphBase {
1120 ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
1122 ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
1124 ListUGraph(const ListUGraph &) :ExtendedListUGraphBase() {};
1125 ///\brief Assignment of ListUGraph to another one is \e not allowed.
1126 ///Use UGraphCopy() instead.
1128 ///Assignment of ListUGraph to another one is \e not allowed.
1129 ///Use UGraphCopy() instead.
1130 void operator=(const ListUGraph &) {}
1138 typedef ExtendedListUGraphBase Parent;
1140 typedef Parent::OutEdgeIt IncEdgeIt;
1142 /// \brief Add a new node to the graph.
1144 /// \return the new node.
1146 Node addNode() { return Parent::addNode(); }
1148 /// \brief Add a new edge to the graph.
1150 /// Add a new edge to the graph with source node \c s
1151 /// and target node \c t.
1152 /// \return the new undirected edge.
1153 UEdge addEdge(const Node& s, const Node& t) {
1154 return Parent::addEdge(s, t);
1156 /// \brief Changes the source of \c e to \c n
1158 /// Changes the source of \c e to \c n
1160 ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
1161 ///referencing the changed edge remain
1162 ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
1163 void changeSource(UEdge e, Node n) {
1164 Parent::changeSource(e,n);
1166 /// \brief Changes the target of \c e to \c n
1168 /// Changes the target of \c e to \c n
1170 /// \note The <tt>EdgeIt</tt>s referencing the changed edge remain
1171 /// valid. However the other iterators may be invalidated.
1172 void changeTarget(UEdge e, Node n) {
1173 Parent::changeTarget(e,n);
1175 /// \brief Changes the source of \c e to \c n
1177 /// Changes the source of \c e to \c n. It changes the proper
1178 /// node of the represented undirected edge.
1180 ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
1181 ///referencing the changed edge remain
1182 ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
1183 void changeSource(Edge e, Node n) {
1184 if (Parent::direction(e)) {
1185 Parent::changeSource(e,n);
1187 Parent::changeTarget(e,n);
1190 /// \brief Changes the target of \c e to \c n
1192 /// Changes the target of \c e to \c n. It changes the proper
1193 /// node of the represented undirected edge.
1195 ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1196 ///referencing the changed edge remain
1197 ///valid. However <tt>InEdgeIt</tt>s are invalidated.
1198 void changeTarget(Edge e, Node n) {
1199 if (Parent::direction(e)) {
1200 Parent::changeTarget(e,n);
1202 Parent::changeSource(e,n);
1205 /// \brief Contract two nodes.
1207 /// This function contracts two nodes.
1209 /// Node \p b will be removed but instead of deleting
1210 /// its neighboring edges, they will be joined to \p a.
1211 /// The last parameter \p r controls whether to remove loops. \c true
1212 /// means that loops will be removed.
1214 /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
1216 void contract(Node a, Node b, bool r = true) {
1217 for(IncEdgeIt e(*this, b); e!=INVALID;) {
1218 IncEdgeIt f = e; ++f;
1219 if (r && runningNode(e) == a) {
1221 } else if (source(e) == b) {
1232 /// \brief Class to make a snapshot of the graph and restore
1235 /// Class to make a snapshot of the graph and to restore it
1238 /// The newly added nodes and undirected edges can be removed
1239 /// using the restore() function.
1241 /// \warning Edge and node deletions cannot be restored. This
1242 /// events invalidate the snapshot.
1246 typedef Parent::NodeNotifier NodeNotifier;
1248 class NodeObserverProxy : public NodeNotifier::ObserverBase {
1251 NodeObserverProxy(Snapshot& _snapshot)
1252 : snapshot(_snapshot) {}
1254 using NodeNotifier::ObserverBase::attach;
1255 using NodeNotifier::ObserverBase::detach;
1256 using NodeNotifier::ObserverBase::attached;
1260 virtual void add(const Node& node) {
1261 snapshot.addNode(node);
1263 virtual void add(const std::vector<Node>& nodes) {
1264 for (int i = nodes.size() - 1; i >= 0; ++i) {
1265 snapshot.addNode(nodes[i]);
1268 virtual void erase(const Node& node) {
1269 snapshot.eraseNode(node);
1271 virtual void erase(const std::vector<Node>& nodes) {
1272 for (int i = 0; i < (int)nodes.size(); ++i) {
1273 snapshot.eraseNode(nodes[i]);
1276 virtual void build() {
1277 NodeNotifier* _notifier = notifier();
1279 std::vector<Node> nodes;
1280 for (_notifier->first(node); node != INVALID;
1281 _notifier->next(node)) {
1282 nodes.push_back(node);
1284 for (int i = nodes.size() - 1; i >= 0; --i) {
1285 snapshot.addNode(nodes[i]);
1288 virtual void clear() {
1289 NodeNotifier* _notifier = notifier();
1291 for (_notifier->first(node); node != INVALID;
1292 _notifier->next(node)) {
1293 snapshot.eraseNode(node);
1300 class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
1303 UEdgeObserverProxy(Snapshot& _snapshot)
1304 : snapshot(_snapshot) {}
1306 using UEdgeNotifier::ObserverBase::attach;
1307 using UEdgeNotifier::ObserverBase::detach;
1308 using UEdgeNotifier::ObserverBase::attached;
1312 virtual void add(const UEdge& edge) {
1313 snapshot.addUEdge(edge);
1315 virtual void add(const std::vector<UEdge>& edges) {
1316 for (int i = edges.size() - 1; i >= 0; ++i) {
1317 snapshot.addUEdge(edges[i]);
1320 virtual void erase(const UEdge& edge) {
1321 snapshot.eraseUEdge(edge);
1323 virtual void erase(const std::vector<UEdge>& edges) {
1324 for (int i = 0; i < (int)edges.size(); ++i) {
1325 snapshot.eraseUEdge(edges[i]);
1328 virtual void build() {
1329 UEdgeNotifier* _notifier = notifier();
1331 std::vector<UEdge> edges;
1332 for (_notifier->first(edge); edge != INVALID;
1333 _notifier->next(edge)) {
1334 edges.push_back(edge);
1336 for (int i = edges.size() - 1; i >= 0; --i) {
1337 snapshot.addUEdge(edges[i]);
1340 virtual void clear() {
1341 UEdgeNotifier* _notifier = notifier();
1343 for (_notifier->first(edge); edge != INVALID;
1344 _notifier->next(edge)) {
1345 snapshot.eraseUEdge(edge);
1354 NodeObserverProxy node_observer_proxy;
1355 UEdgeObserverProxy edge_observer_proxy;
1357 std::list<Node> added_nodes;
1358 std::list<UEdge> added_edges;
1361 void addNode(const Node& node) {
1362 added_nodes.push_front(node);
1364 void eraseNode(const Node& node) {
1365 std::list<Node>::iterator it =
1366 std::find(added_nodes.begin(), added_nodes.end(), node);
1367 if (it == added_nodes.end()) {
1369 edge_observer_proxy.detach();
1370 throw NodeNotifier::ImmediateDetach();
1372 added_nodes.erase(it);
1376 void addUEdge(const UEdge& edge) {
1377 added_edges.push_front(edge);
1379 void eraseUEdge(const UEdge& edge) {
1380 std::list<UEdge>::iterator it =
1381 std::find(added_edges.begin(), added_edges.end(), edge);
1382 if (it == added_edges.end()) {
1384 node_observer_proxy.detach();
1385 throw UEdgeNotifier::ImmediateDetach();
1387 added_edges.erase(it);
1391 void attach(ListUGraph &_graph) {
1393 node_observer_proxy.attach(graph->notifier(Node()));
1394 edge_observer_proxy.attach(graph->notifier(UEdge()));
1398 node_observer_proxy.detach();
1399 edge_observer_proxy.detach();
1402 bool attached() const {
1403 return node_observer_proxy.attached();
1407 added_nodes.clear();
1408 added_edges.clear();
1413 /// \brief Default constructor.
1415 /// Default constructor.
1416 /// To actually make a snapshot you must call save().
1418 : graph(0), node_observer_proxy(*this),
1419 edge_observer_proxy(*this) {}
1421 /// \brief Constructor that immediately makes a snapshot.
1423 /// This constructor immediately makes a snapshot of the graph.
1424 /// \param _graph The graph we make a snapshot of.
1425 Snapshot(ListUGraph &_graph)
1426 : node_observer_proxy(*this),
1427 edge_observer_proxy(*this) {
1431 /// \brief Make a snapshot.
1433 /// Make a snapshot of the graph.
1435 /// This function can be called more than once. In case of a repeated
1436 /// call, the previous snapshot gets lost.
1437 /// \param _graph The graph we make the snapshot of.
1438 void save(ListUGraph &_graph) {
1446 /// \brief Undo the changes until the last snapshot.
1448 /// Undo the changes until the last snapshot created by save().
1451 for(std::list<UEdge>::iterator it = added_edges.begin();
1452 it != added_edges.end(); ++it) {
1455 for(std::list<Node>::iterator it = added_nodes.begin();
1456 it != added_nodes.end(); ++it) {
1462 /// \brief Gives back true when the snapshot is valid.
1464 /// Gives back true when the snapshot is valid.
1465 bool valid() const {
1472 class ListBpUGraphBase {
1475 class NodeSetError : public LogicError {
1477 virtual const char* what() const throw() {
1478 return "lemon::ListBpUGraph::NodeSetError";
1485 int first_edge, prev, next;
1489 int aNode, prev_out, next_out;
1490 int bNode, prev_in, next_in;
1493 std::vector<NodeT> aNodes;
1494 std::vector<NodeT> bNodes;
1496 std::vector<UEdgeT> edges;
1499 int first_free_anode;
1502 int first_free_bnode;
1504 int first_free_edge;
1509 friend class ListBpUGraphBase;
1513 explicit Node(int _id) : id(_id) {}
1516 Node(Invalid) { id = -1; }
1517 bool operator==(const Node i) const {return id==i.id;}
1518 bool operator!=(const Node i) const {return id!=i.id;}
1519 bool operator<(const Node i) const {return id<i.id;}
1523 friend class ListBpUGraphBase;
1527 explicit UEdge(int _id) { id = _id;}
1530 UEdge (Invalid) { id = -1; }
1531 bool operator==(const UEdge i) const {return id==i.id;}
1532 bool operator!=(const UEdge i) const {return id!=i.id;}
1533 bool operator<(const UEdge i) const {return id<i.id;}
1537 : first_anode(-1), first_free_anode(-1),
1538 first_bnode(-1), first_free_bnode(-1),
1539 first_free_edge(-1) {}
1541 void firstANode(Node& node) const {
1542 node.id = first_anode != -1 ? (first_anode << 1) : -1;
1544 void nextANode(Node& node) const {
1545 node.id = aNodes[node.id >> 1].next;
1548 void firstBNode(Node& node) const {
1549 node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
1551 void nextBNode(Node& node) const {
1552 node.id = bNodes[node.id >> 1].next;
1555 void first(Node& node) const {
1556 if (first_anode != -1) {
1557 node.id = (first_anode << 1);
1558 } else if (first_bnode != -1) {
1559 node.id = (first_bnode << 1) + 1;
1564 void next(Node& node) const {
1566 node.id = aNodes[node.id >> 1].next;
1567 if (node.id == -1) {
1568 if (first_bnode != -1) {
1569 node.id = (first_bnode << 1) + 1;
1573 node.id = bNodes[node.id >> 1].next;
1577 void first(UEdge& edge) const {
1578 int aNodeId = first_anode;
1579 while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
1580 aNodeId = aNodes[aNodeId].next != -1 ?
1581 aNodes[aNodeId].next >> 1 : -1;
1583 if (aNodeId != -1) {
1584 edge.id = aNodes[aNodeId].first_edge;
1589 void next(UEdge& edge) const {
1590 int aNodeId = edges[edge.id].aNode >> 1;
1591 edge.id = edges[edge.id].next_out;
1592 if (edge.id == -1) {
1593 aNodeId = aNodes[aNodeId].next != -1 ?
1594 aNodes[aNodeId].next >> 1 : -1;
1595 while (aNodeId != -1 && aNodes[aNodeId].first_edge == -1) {
1596 aNodeId = aNodes[aNodeId].next != -1 ?
1597 aNodes[aNodeId].next >> 1 : -1;
1599 if (aNodeId != -1) {
1600 edge.id = aNodes[aNodeId].first_edge;
1607 void firstFromANode(UEdge& edge, const Node& node) const {
1608 LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
1609 edge.id = aNodes[node.id >> 1].first_edge;
1611 void nextFromANode(UEdge& edge) const {
1612 edge.id = edges[edge.id].next_out;
1615 void firstFromBNode(UEdge& edge, const Node& node) const {
1616 LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
1617 edge.id = bNodes[node.id >> 1].first_edge;
1619 void nextFromBNode(UEdge& edge) const {
1620 edge.id = edges[edge.id].next_in;
1623 static int id(const Node& node) {
1626 static Node nodeFromId(int id) {
1629 int maxNodeId() const {
1630 return aNodes.size() > bNodes.size() ?
1631 aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
1634 static int id(const UEdge& edge) {
1637 static UEdge uEdgeFromId(int id) {
1640 int maxUEdgeId() const {
1641 return edges.size();
1644 static int aNodeId(const Node& node) {
1645 return node.id >> 1;
1647 static Node nodeFromANodeId(int id) {
1648 return Node(id << 1);
1650 int maxANodeId() const {
1651 return aNodes.size();
1654 static int bNodeId(const Node& node) {
1655 return node.id >> 1;
1657 static Node nodeFromBNodeId(int id) {
1658 return Node((id << 1) + 1);
1660 int maxBNodeId() const {
1661 return bNodes.size();
1664 Node aNode(const UEdge& edge) const {
1665 return Node(edges[edge.id].aNode);
1667 Node bNode(const UEdge& edge) const {
1668 return Node(edges[edge.id].bNode);
1671 static bool aNode(const Node& node) {
1672 return (node.id & 1) == 0;
1675 static bool bNode(const Node& node) {
1676 return (node.id & 1) == 1;
1681 if (first_free_anode == -1) {
1682 aNodeId = aNodes.size();
1683 aNodes.push_back(NodeT());
1685 aNodeId = first_free_anode;
1686 first_free_anode = aNodes[first_free_anode].next;
1688 if (first_anode != -1) {
1689 aNodes[aNodeId].next = first_anode << 1;
1690 aNodes[first_anode].prev = aNodeId << 1;
1692 aNodes[aNodeId].next = -1;
1694 aNodes[aNodeId].prev = -1;
1695 first_anode = aNodeId;
1696 aNodes[aNodeId].first_edge = -1;
1697 return Node(aNodeId << 1);
1702 if (first_free_bnode == -1) {
1703 bNodeId = bNodes.size();
1704 bNodes.push_back(NodeT());
1706 bNodeId = first_free_bnode;
1707 first_free_bnode = bNodes[first_free_bnode].next;
1709 if (first_bnode != -1) {
1710 bNodes[bNodeId].next = (first_bnode << 1) + 1;
1711 bNodes[first_bnode].prev = (bNodeId << 1) + 1;
1713 bNodes[bNodeId].next = -1;
1715 bNodes[bNodeId].prev = -1;
1716 first_bnode = bNodeId;
1717 bNodes[bNodeId].first_edge = -1;
1718 return Node((bNodeId << 1) + 1);
1721 UEdge addEdge(const Node& source, const Node& target) {
1722 LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
1724 if (first_free_edge != -1) {
1725 edgeId = first_free_edge;
1726 first_free_edge = edges[edgeId].next_out;
1728 edgeId = edges.size();
1729 edges.push_back(UEdgeT());
1731 if ((source.id & 1) == 0) {
1732 edges[edgeId].aNode = source.id;
1733 edges[edgeId].bNode = target.id;
1735 edges[edgeId].aNode = target.id;
1736 edges[edgeId].bNode = source.id;
1738 edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
1739 edges[edgeId].prev_out = -1;
1740 if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
1741 edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
1743 aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
1744 edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
1745 edges[edgeId].prev_in = -1;
1746 if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
1747 edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
1749 bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
1750 return UEdge(edgeId);
1753 void erase(const Node& node) {
1755 int aNodeId = node.id >> 1;
1756 if (aNodes[aNodeId].prev != -1) {
1757 aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
1760 aNodes[aNodeId].next != -1 ? aNodes[aNodeId].next >> 1 : -1;
1762 if (aNodes[aNodeId].next != -1) {
1763 aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
1765 aNodes[aNodeId].next = first_free_anode;
1766 first_free_anode = aNodeId;
1768 int bNodeId = node.id >> 1;
1769 if (bNodes[bNodeId].prev != -1) {
1770 bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
1773 bNodes[bNodeId].next != -1 ? bNodes[bNodeId].next >> 1 : -1;
1775 if (bNodes[bNodeId].next != -1) {
1776 bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
1778 bNodes[bNodeId].next = first_free_bnode;
1779 first_free_bnode = bNodeId;
1783 void erase(const UEdge& edge) {
1785 if (edges[edge.id].prev_out != -1) {
1786 edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
1788 aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
1790 if (edges[edge.id].next_out != -1) {
1791 edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
1794 if (edges[edge.id].prev_in != -1) {
1795 edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
1797 bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
1799 if (edges[edge.id].next_in != -1) {
1800 edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
1803 edges[edge.id].next_out = first_free_edge;
1804 first_free_edge = edge.id;
1812 first_free_anode = -1;
1814 first_free_bnode = -1;
1815 first_free_edge = -1;
1818 void changeANode(const UEdge& edge, const Node& node) {
1819 LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
1820 if (edges[edge.id].prev_out != -1) {
1821 edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
1823 aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
1825 if (edges[edge.id].next_out != -1) {
1826 edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
1828 if (aNodes[node.id >> 1].first_edge != -1) {
1829 edges[aNodes[node.id >> 1].first_edge].prev_out = edge.id;
1831 edges[edge.id].prev_out = -1;
1832 edges[edge.id].next_out = aNodes[node.id >> 1].first_edge;
1833 aNodes[node.id >> 1].first_edge = edge.id;
1834 edges[edge.id].aNode = node.id;
1837 void changeBNode(const UEdge& edge, const Node& node) {
1838 LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
1839 if (edges[edge.id].prev_in != -1) {
1840 edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
1842 bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
1844 if (edges[edge.id].next_in != -1) {
1845 edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
1847 if (bNodes[node.id >> 1].first_edge != -1) {
1848 edges[bNodes[node.id >> 1].first_edge].prev_in = edge.id;
1850 edges[edge.id].prev_in = -1;
1851 edges[edge.id].next_in = bNodes[node.id >> 1].first_edge;
1852 bNodes[node.id >> 1].first_edge = edge.id;
1853 edges[edge.id].bNode = node.id;
1859 typedef BpUGraphExtender<BidirBpUGraphExtender<ListBpUGraphBase> >
1860 ExtendedListBpUGraphBase;
1864 /// \brief A smart bipartite undirected graph class.
1866 /// This is a bipartite undirected graph implementation.
1867 /// It is conforms to the \ref concepts::BpUGraph "BpUGraph concept".
1869 ///An important extra feature of this graph implementation is that
1870 ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1872 /// \sa concepts::BpUGraph.
1874 class ListBpUGraph : public ExtendedListBpUGraphBase {
1875 /// \brief ListBpUGraph is \e not copy constructible.
1877 ///ListBpUGraph is \e not copy constructible.
1878 ListBpUGraph(const ListBpUGraph &) :ExtendedListBpUGraphBase() {};
1879 /// \brief Assignment of ListBpUGraph to another one is \e not
1882 /// Assignment of ListBpUGraph to another one is \e not allowed.
1883 void operator=(const ListBpUGraph &) {}
1885 /// \brief Constructor
1891 typedef ExtendedListBpUGraphBase Parent;
1892 /// \brief Add a new ANode to the graph.
1894 /// \return the new node.
1896 Node addANode() { return Parent::addANode(); }
1898 /// \brief Add a new BNode to the graph.
1900 /// \return the new node.
1902 Node addBNode() { return Parent::addBNode(); }
1904 /// \brief Add a new edge to the graph.
1906 /// Add a new edge to the graph with an ANode and a BNode.
1907 /// \return the new undirected edge.
1908 UEdge addEdge(const Node& s, const Node& t) {
1909 return Parent::addEdge(s, t);
1912 /// \brief Changes the ANode of \c e to \c n
1914 /// Changes the ANode of \c e to \c n
1916 ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
1917 ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
1919 void changeANode(UEdge e, Node n) {
1920 Parent::changeANode(e,n);
1923 /// \brief Changes the BNode of \c e to \c n
1925 /// Changes the BNode of \c e to \c n
1927 /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1928 /// referencing the changed edge remain
1929 /// valid. However <tt>InEdgeIt</tt>s are invalidated.
1930 void changeBNode(UEdge e, Node n) {
1931 Parent::changeBNode(e,n);
1934 /// \brief Changes the source(ANode) of \c e to \c n
1936 /// Changes the source(ANode) of \c e to \c n
1938 ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
1939 ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
1941 void changeSource(UEdge e, Node n) {
1942 Parent::changeANode(e,n);
1945 /// \brief Changes the target(BNode) of \c e to \c n
1947 /// Changes the target(BNode) of \c e to \c n
1949 /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1950 /// referencing the changed edge remain
1951 /// valid. However <tt>InEdgeIt</tt>s are invalidated.
1952 void changeTarget(UEdge e, Node n) {
1953 Parent::changeBNode(e,n);
1956 /// \brief Changes the source of \c e to \c n
1958 /// Changes the source of \c e to \c n. It changes the proper
1959 /// node of the represented undirected edge.
1961 ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
1962 ///referencing the changed edge remain
1963 ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
1964 void changeSource(Edge e, Node n) {
1965 if (Parent::direction(e)) {
1966 Parent::changeANode(e,n);
1968 Parent::changeBNode(e,n);
1971 /// \brief Changes the target of \c e to \c n
1973 /// Changes the target of \c e to \c n. It changes the proper
1974 /// node of the represented undirected edge.
1976 ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
1977 ///referencing the changed edge remain
1978 ///valid. However <tt>InEdgeIt</tt>s are invalidated.
1979 void changeTarget(Edge e, Node n) {
1980 if (Parent::direction(e)) {
1981 Parent::changeBNode(e,n);
1983 Parent::changeANode(e,n);
1986 /// \brief Contract two nodes.
1988 /// This function contracts two nodes.
1990 /// Node \p b will be removed but instead of deleting its
1991 /// neighboring edges, they will be joined to \p a. The two nodes
1992 /// should be from the same nodeset, of course.
1994 /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
1996 void contract(const Node& a, const Node& b) {
1997 LEMON_ASSERT(Parent::aNode(a) == Parent::aNode(b), NodeSetError());
1998 if (Parent::aNode(a)) {
1999 for (IncEdgeIt e(*this, b); e!=INVALID;) {
2000 IncEdgeIt f = e; ++f;
2005 for (IncEdgeIt e(*this, b); e!=INVALID;) {
2006 IncEdgeIt f = e; ++f;
2014 /// \brief Class to make a snapshot of the graph and restore
2017 /// Class to make a snapshot of the graph and to restore it
2020 /// The newly added nodes and undirected edges can be removed
2021 /// using the restore() function.
2023 /// \warning Edge and node deletions cannot be restored. This
2024 /// events invalidate the snapshot.
2028 typedef Parent::NodeNotifier NodeNotifier;
2030 class NodeObserverProxy : public NodeNotifier::ObserverBase {
2033 NodeObserverProxy(Snapshot& _snapshot)
2034 : snapshot(_snapshot) {}
2036 using NodeNotifier::ObserverBase::attach;
2037 using NodeNotifier::ObserverBase::detach;
2038 using NodeNotifier::ObserverBase::attached;
2042 virtual void add(const Node& node) {
2043 snapshot.addNode(node);
2045 virtual void add(const std::vector<Node>& nodes) {
2046 for (int i = nodes.size() - 1; i >= 0; ++i) {
2047 snapshot.addNode(nodes[i]);
2050 virtual void erase(const Node& node) {
2051 snapshot.eraseNode(node);
2053 virtual void erase(const std::vector<Node>& nodes) {
2054 for (int i = 0; i < (int)nodes.size(); ++i) {
2055 snapshot.eraseNode(nodes[i]);
2058 virtual void build() {
2059 NodeNotifier* _notifier = notifier();
2061 std::vector<Node> nodes;
2062 for (_notifier->first(node); node != INVALID;
2063 _notifier->next(node)) {
2064 nodes.push_back(node);
2066 for (int i = nodes.size() - 1; i >= 0; --i) {
2067 snapshot.addNode(nodes[i]);
2070 virtual void clear() {
2071 NodeNotifier* _notifier = notifier();
2073 for (_notifier->first(node); node != INVALID;
2074 _notifier->next(node)) {
2075 snapshot.eraseNode(node);
2082 class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
2085 UEdgeObserverProxy(Snapshot& _snapshot)
2086 : snapshot(_snapshot) {}
2088 using UEdgeNotifier::ObserverBase::attach;
2089 using UEdgeNotifier::ObserverBase::detach;
2090 using UEdgeNotifier::ObserverBase::attached;
2094 virtual void add(const UEdge& edge) {
2095 snapshot.addUEdge(edge);
2097 virtual void add(const std::vector<UEdge>& edges) {
2098 for (int i = edges.size() - 1; i >= 0; ++i) {
2099 snapshot.addUEdge(edges[i]);
2102 virtual void erase(const UEdge& edge) {
2103 snapshot.eraseUEdge(edge);
2105 virtual void erase(const std::vector<UEdge>& edges) {
2106 for (int i = 0; i < (int)edges.size(); ++i) {
2107 snapshot.eraseUEdge(edges[i]);
2110 virtual void build() {
2111 UEdgeNotifier* _notifier = notifier();
2113 std::vector<UEdge> edges;
2114 for (_notifier->first(edge); edge != INVALID;
2115 _notifier->next(edge)) {
2116 edges.push_back(edge);
2118 for (int i = edges.size() - 1; i >= 0; --i) {
2119 snapshot.addUEdge(edges[i]);
2122 virtual void clear() {
2123 UEdgeNotifier* _notifier = notifier();
2125 for (_notifier->first(edge); edge != INVALID;
2126 _notifier->next(edge)) {
2127 snapshot.eraseUEdge(edge);
2134 ListBpUGraph *graph;
2136 NodeObserverProxy node_observer_proxy;
2137 UEdgeObserverProxy edge_observer_proxy;
2139 std::list<Node> added_nodes;
2140 std::list<UEdge> added_edges;
2143 void addNode(const Node& node) {
2144 added_nodes.push_front(node);
2146 void eraseNode(const Node& node) {
2147 std::list<Node>::iterator it =
2148 std::find(added_nodes.begin(), added_nodes.end(), node);
2149 if (it == added_nodes.end()) {
2151 edge_observer_proxy.detach();
2152 throw NodeNotifier::ImmediateDetach();
2154 added_nodes.erase(it);
2158 void addUEdge(const UEdge& edge) {
2159 added_edges.push_front(edge);
2161 void eraseUEdge(const UEdge& edge) {
2162 std::list<UEdge>::iterator it =
2163 std::find(added_edges.begin(), added_edges.end(), edge);
2164 if (it == added_edges.end()) {
2166 node_observer_proxy.detach();
2167 throw UEdgeNotifier::ImmediateDetach();
2169 added_edges.erase(it);
2173 void attach(ListBpUGraph &_graph) {
2175 node_observer_proxy.attach(graph->notifier(Node()));
2176 edge_observer_proxy.attach(graph->notifier(UEdge()));
2180 node_observer_proxy.detach();
2181 edge_observer_proxy.detach();
2184 bool attached() const {
2185 return node_observer_proxy.attached();
2189 added_nodes.clear();
2190 added_edges.clear();
2195 /// \brief Default constructor.
2197 /// Default constructor.
2198 /// To actually make a snapshot you must call save().
2200 : graph(0), node_observer_proxy(*this),
2201 edge_observer_proxy(*this) {}
2203 /// \brief Constructor that immediately makes a snapshot.
2205 /// This constructor immediately makes a snapshot of the graph.
2206 /// \param _graph The graph we make a snapshot of.
2207 Snapshot(ListBpUGraph &_graph)
2208 : node_observer_proxy(*this),
2209 edge_observer_proxy(*this) {
2213 /// \brief Make a snapshot.
2215 /// Make a snapshot of the graph.
2217 /// This function can be called more than once. In case of a repeated
2218 /// call, the previous snapshot gets lost.
2219 /// \param _graph The graph we make the snapshot of.
2220 void save(ListBpUGraph &_graph) {
2228 /// \brief Undo the changes until the last snapshot.
2230 /// Undo the changes until the last snapshot created by save().
2233 for(std::list<UEdge>::iterator it = added_edges.begin();
2234 it != added_edges.end(); ++it) {
2237 for(std::list<Node>::iterator it = added_nodes.begin();
2238 it != added_nodes.end(); ++it) {
2244 /// \brief Gives back true when the snapshot is valid.
2246 /// Gives back true when the snapshot is valid.
2247 bool valid() const {