1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_EDGE_SET_H
20 #define LEMON_EDGE_SET_H
22 #include <lemon/core.h>
23 #include <lemon/bits/edge_set_extender.h>
25 /// \ingroup semi_adaptors
27 /// \brief ArcSet and EdgeSet classes.
29 /// Graphs which use another graph's node-set as own.
32 template <typename GR>
33 class ListArcSetBase {
37 typedef typename GR::Node Node;
38 typedef typename GR::NodeIt NodeIt;
43 int first_out, first_in;
44 NodeT() : first_out(-1), first_in(-1) {}
47 typedef typename ItemSetTraits<GR, Node>::
48 template Map<NodeT>::Type NodesImplBase;
50 NodesImplBase* _nodes;
54 int next_out, next_in;
55 int prev_out, prev_in;
56 ArcT() : prev_out(-1), prev_in(-1) {}
59 std::vector<ArcT> arcs;
66 void initalize(const GR& graph, NodesImplBase& nodes) {
74 friend class ListArcSetBase<GR>;
76 Arc(int _id) : id(_id) {}
80 Arc(Invalid) : id(-1) {}
81 bool operator==(const Arc& arc) const { return id == arc.id; }
82 bool operator!=(const Arc& arc) const { return id != arc.id; }
83 bool operator<(const Arc& arc) const { return id < arc.id; }
86 ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
88 Arc addArc(const Node& u, const Node& v) {
90 if (first_free_arc == -1) {
92 arcs.push_back(ArcT());
95 first_free_arc = arcs[first_free_arc].next_in;
97 arcs[n].next_in = (*_nodes)[v].first_in;
98 if ((*_nodes)[v].first_in != -1) {
99 arcs[(*_nodes)[v].first_in].prev_in = n;
101 (*_nodes)[v].first_in = n;
102 arcs[n].next_out = (*_nodes)[u].first_out;
103 if ((*_nodes)[u].first_out != -1) {
104 arcs[(*_nodes)[u].first_out].prev_out = n;
106 (*_nodes)[u].first_out = n;
112 void erase(const Arc& arc) {
114 if (arcs[n].prev_in != -1) {
115 arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
117 (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
119 if (arcs[n].next_in != -1) {
120 arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
123 if (arcs[n].prev_out != -1) {
124 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
126 (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
128 if (arcs[n].next_out != -1) {
129 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
136 for (first(node); node != INVALID; next(node)) {
137 (*_nodes)[node].first_in = -1;
138 (*_nodes)[node].first_out = -1;
145 void first(Node& node) const {
149 void next(Node& node) const {
153 void first(Arc& arc) const {
156 while (node != INVALID && (*_nodes)[node].first_in == -1) {
159 arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
162 void next(Arc& arc) const {
163 if (arcs[arc.id].next_in != -1) {
164 arc.id = arcs[arc.id].next_in;
166 Node node = arcs[arc.id].target;
168 while (node != INVALID && (*_nodes)[node].first_in == -1) {
171 arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
175 void firstOut(Arc& arc, const Node& node) const {
176 arc.id = (*_nodes)[node].first_out;
179 void nextOut(Arc& arc) const {
180 arc.id = arcs[arc.id].next_out;
183 void firstIn(Arc& arc, const Node& node) const {
184 arc.id = (*_nodes)[node].first_in;
187 void nextIn(Arc& arc) const {
188 arc.id = arcs[arc.id].next_in;
191 int id(const Node& node) const { return _graph->id(node); }
192 int id(const Arc& arc) const { return arc.id; }
194 Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
195 Arc arcFromId(int ix) const { return Arc(ix); }
197 int maxNodeId() const { return _graph->maxNodeId(); };
198 int maxArcId() const { return arcs.size() - 1; }
200 Node source(const Arc& arc) const { return arcs[arc.id].source;}
201 Node target(const Arc& arc) const { return arcs[arc.id].target;}
203 typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
205 NodeNotifier& notifier(Node) const {
206 return _graph->notifier(Node());
209 template <typename V>
210 class NodeMap : public GR::template NodeMap<V> {
213 typedef typename GR::template NodeMap<V> Parent;
215 explicit NodeMap(const ListArcSetBase<GR>& arcset)
216 : Parent(*arcset._graph) {}
218 NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
219 : Parent(*arcset._graph, value) {}
221 NodeMap& operator=(const NodeMap& cmap) {
222 return operator=<NodeMap>(cmap);
225 template <typename CMap>
226 NodeMap& operator=(const CMap& cmap) {
227 Parent::operator=(cmap);
234 /// \ingroup semi_adaptors
236 /// \brief Digraph using a node set of another digraph or graph and
239 /// This structure can be used to establish another directed graph
240 /// over a node set of an existing one. This class uses the same
241 /// Node type as the underlying graph, and each valid node of the
242 /// original graph is valid in this arc set, therefore the node
243 /// objects of the original graph can be used directly with this
244 /// class. The node handling functions (id handling, observing, and
245 /// iterators) works equivalently as in the original graph.
247 /// This implementation is based on doubly-linked lists, from each
248 /// node the outgoing and the incoming arcs make up lists, therefore
249 /// one arc can be erased in constant time. It also makes possible,
250 /// that node can be removed from the underlying graph, in this case
251 /// all arcs incident to the given node is erased from the arc set.
253 /// \param GR The type of the graph which shares its node set with
254 /// this class. Its interface must conform to the
255 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
258 /// This class is fully conform to the \ref concepts::Digraph
259 /// "Digraph" concept.
260 template <typename GR>
261 class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
265 typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
267 typedef typename Parent::Node Node;
268 typedef typename Parent::Arc Arc;
273 typedef typename Parent::NodesImplBase NodesImplBase;
275 void eraseNode(const Node& node) {
277 Parent::firstOut(arc, node);
278 while (arc != INVALID ) {
280 Parent::firstOut(arc, node);
283 Parent::firstIn(arc, node);
284 while (arc != INVALID ) {
286 Parent::firstIn(arc, node);
294 class NodesImpl : public NodesImplBase {
296 typedef NodesImplBase Parent;
298 NodesImpl(const GR& graph, ListArcSet& arcset)
299 : Parent(graph), _arcset(arcset) {}
301 virtual ~NodesImpl() {}
305 virtual void erase(const Node& node) {
306 _arcset.eraseNode(node);
309 virtual void erase(const std::vector<Node>& nodes) {
310 for (int i = 0; i < int(nodes.size()); ++i) {
311 _arcset.eraseNode(nodes[i]);
313 Parent::erase(nodes);
315 virtual void clear() {
316 _arcset.clearNodes();
328 /// \brief Constructor of the ArcSet.
330 /// Constructor of the ArcSet.
331 ListArcSet(const GR& graph) : _nodes(graph, *this) {
332 Parent::initalize(graph, _nodes);
335 /// \brief Add a new arc to the digraph.
337 /// Add a new arc to the digraph with source node \c s
338 /// and target node \c t.
339 /// \return the new arc.
340 Arc addArc(const Node& s, const Node& t) {
341 return Parent::addArc(s, t);
344 /// \brief Erase an arc from the digraph.
346 /// Erase an arc \c a from the digraph.
347 void erase(const Arc& a) {
348 return Parent::erase(a);
353 template <typename GR>
354 class ListEdgeSetBase {
358 typedef typename GR::Node Node;
359 typedef typename GR::NodeIt NodeIt;
365 NodeT() : first_out(-1) {}
368 typedef typename ItemSetTraits<GR, Node>::
369 template Map<NodeT>::Type NodesImplBase;
371 NodesImplBase* _nodes;
375 int prev_out, next_out;
376 ArcT() : prev_out(-1), next_out(-1) {}
379 std::vector<ArcT> arcs;
386 void initalize(const GR& graph, NodesImplBase& nodes) {
394 friend class ListEdgeSetBase;
398 explicit Edge(int _id) { id = _id;}
402 Edge (Invalid) { id = -1; }
403 bool operator==(const Edge& arc) const {return id == arc.id;}
404 bool operator!=(const Edge& arc) const {return id != arc.id;}
405 bool operator<(const Edge& arc) const {return id < arc.id;}
409 friend class ListEdgeSetBase;
411 Arc(int _id) : id(_id) {}
414 operator Edge() const { return edgeFromId(id / 2); }
417 Arc(Invalid) : id(-1) {}
418 bool operator==(const Arc& arc) const { return id == arc.id; }
419 bool operator!=(const Arc& arc) const { return id != arc.id; }
420 bool operator<(const Arc& arc) const { return id < arc.id; }
423 ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
425 Edge addEdge(const Node& u, const Node& v) {
428 if (first_free_arc == -1) {
430 arcs.push_back(ArcT());
431 arcs.push_back(ArcT());
434 first_free_arc = arcs[n].next_out;
438 arcs[n | 1].target = v;
440 arcs[n].next_out = (*_nodes)[v].first_out;
441 if ((*_nodes)[v].first_out != -1) {
442 arcs[(*_nodes)[v].first_out].prev_out = n;
444 (*_nodes)[v].first_out = n;
445 arcs[n].prev_out = -1;
447 if ((*_nodes)[u].first_out != -1) {
448 arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
450 arcs[n | 1].next_out = (*_nodes)[u].first_out;
451 (*_nodes)[u].first_out = (n | 1);
452 arcs[n | 1].prev_out = -1;
457 void erase(const Edge& arc) {
460 if (arcs[n].next_out != -1) {
461 arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
464 if (arcs[n].prev_out != -1) {
465 arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
467 (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
470 if (arcs[n | 1].next_out != -1) {
471 arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
474 if (arcs[n | 1].prev_out != -1) {
475 arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
477 (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
480 arcs[n].next_out = first_free_arc;
487 for (first(node); node != INVALID; next(node)) {
488 (*_nodes)[node].first_out = -1;
495 void first(Node& node) const {
499 void next(Node& node) const {
503 void first(Arc& arc) const {
506 while (node != INVALID && (*_nodes)[node].first_out == -1) {
509 arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
512 void next(Arc& arc) const {
513 if (arcs[arc.id].next_out != -1) {
514 arc.id = arcs[arc.id].next_out;
516 Node node = arcs[arc.id ^ 1].target;
518 while(node != INVALID && (*_nodes)[node].first_out == -1) {
521 arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
525 void first(Edge& edge) const {
528 while (node != INVALID) {
529 edge.id = (*_nodes)[node].first_out;
530 while ((edge.id & 1) != 1) {
531 edge.id = arcs[edge.id].next_out;
542 void next(Edge& edge) const {
543 Node node = arcs[edge.id * 2].target;
544 edge.id = arcs[(edge.id * 2) | 1].next_out;
545 while ((edge.id & 1) != 1) {
546 edge.id = arcs[edge.id].next_out;
553 while (node != INVALID) {
554 edge.id = (*_nodes)[node].first_out;
555 while ((edge.id & 1) != 1) {
556 edge.id = arcs[edge.id].next_out;
567 void firstOut(Arc& arc, const Node& node) const {
568 arc.id = (*_nodes)[node].first_out;
571 void nextOut(Arc& arc) const {
572 arc.id = arcs[arc.id].next_out;
575 void firstIn(Arc& arc, const Node& node) const {
576 arc.id = (((*_nodes)[node].first_out) ^ 1);
577 if (arc.id == -2) arc.id = -1;
580 void nextIn(Arc& arc) const {
581 arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
582 if (arc.id == -2) arc.id = -1;
585 void firstInc(Edge &arc, bool& dir, const Node& node) const {
586 int de = (*_nodes)[node].first_out;
589 dir = ((de & 1) == 1);
595 void nextInc(Edge &arc, bool& dir) const {
596 int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
599 dir = ((de & 1) == 1);
606 static bool direction(Arc arc) {
607 return (arc.id & 1) == 1;
610 static Arc direct(Edge edge, bool dir) {
611 return Arc(edge.id * 2 + (dir ? 1 : 0));
614 int id(const Node& node) const { return _graph->id(node); }
615 static int id(Arc e) { return e.id; }
616 static int id(Edge e) { return e.id; }
618 Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
619 static Arc arcFromId(int id) { return Arc(id);}
620 static Edge edgeFromId(int id) { return Edge(id);}
622 int maxNodeId() const { return _graph->maxNodeId(); };
623 int maxEdgeId() const { return arcs.size() / 2 - 1; }
624 int maxArcId() const { return arcs.size()-1; }
626 Node source(Arc e) const { return arcs[e.id ^ 1].target; }
627 Node target(Arc e) const { return arcs[e.id].target; }
629 Node u(Edge e) const { return arcs[2 * e.id].target; }
630 Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
632 typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
634 NodeNotifier& notifier(Node) const {
635 return _graph->notifier(Node());
638 template <typename V>
639 class NodeMap : public GR::template NodeMap<V> {
642 typedef typename GR::template NodeMap<V> Parent;
644 explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
645 : Parent(*arcset._graph) {}
647 NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
648 : Parent(*arcset._graph, value) {}
650 NodeMap& operator=(const NodeMap& cmap) {
651 return operator=<NodeMap>(cmap);
654 template <typename CMap>
655 NodeMap& operator=(const CMap& cmap) {
656 Parent::operator=(cmap);
663 /// \ingroup semi_adaptors
665 /// \brief Graph using a node set of another digraph or graph and an
668 /// This structure can be used to establish another graph over a
669 /// node set of an existing one. This class uses the same Node type
670 /// as the underlying graph, and each valid node of the original
671 /// graph is valid in this arc set, therefore the node objects of
672 /// the original graph can be used directly with this class. The
673 /// node handling functions (id handling, observing, and iterators)
674 /// works equivalently as in the original graph.
676 /// This implementation is based on doubly-linked lists, from each
677 /// node the incident edges make up lists, therefore one edge can be
678 /// erased in constant time. It also makes possible, that node can
679 /// be removed from the underlying graph, in this case all edges
680 /// incident to the given node is erased from the arc set.
682 /// \param GR The type of the graph which shares its node set
683 /// with this class. Its interface must conform to the
684 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
687 /// This class is fully conform to the \ref concepts::Graph "Graph"
689 template <typename GR>
690 class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
694 typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
696 typedef typename Parent::Node Node;
697 typedef typename Parent::Arc Arc;
698 typedef typename Parent::Edge Edge;
703 typedef typename Parent::NodesImplBase NodesImplBase;
705 void eraseNode(const Node& node) {
707 Parent::firstOut(arc, node);
708 while (arc != INVALID ) {
710 Parent::firstOut(arc, node);
719 class NodesImpl : public NodesImplBase {
721 typedef NodesImplBase Parent;
723 NodesImpl(const GR& graph, ListEdgeSet& arcset)
724 : Parent(graph), _arcset(arcset) {}
726 virtual ~NodesImpl() {}
730 virtual void erase(const Node& node) {
731 _arcset.eraseNode(node);
734 virtual void erase(const std::vector<Node>& nodes) {
735 for (int i = 0; i < int(nodes.size()); ++i) {
736 _arcset.eraseNode(nodes[i]);
738 Parent::erase(nodes);
740 virtual void clear() {
741 _arcset.clearNodes();
746 ListEdgeSet& _arcset;
753 /// \brief Constructor of the EdgeSet.
755 /// Constructor of the EdgeSet.
756 ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
757 Parent::initalize(graph, _nodes);
760 /// \brief Add a new edge to the graph.
762 /// Add a new edge to the graph with node \c u
763 /// and node \c v endpoints.
764 /// \return the new edge.
765 Edge addEdge(const Node& u, const Node& v) {
766 return Parent::addEdge(u, v);
769 /// \brief Erase an edge from the graph.
771 /// Erase the edge \c e from the graph.
772 void erase(const Edge& e) {
773 return Parent::erase(e);
778 template <typename GR>
779 class SmartArcSetBase {
783 typedef typename Graph::Node Node;
784 typedef typename Graph::NodeIt NodeIt;
789 int first_out, first_in;
790 NodeT() : first_out(-1), first_in(-1) {}
793 typedef typename ItemSetTraits<GR, Node>::
794 template Map<NodeT>::Type NodesImplBase;
796 NodesImplBase* _nodes;
800 int next_out, next_in;
804 std::vector<ArcT> arcs;
808 void initalize(const GR& graph, NodesImplBase& nodes) {
816 friend class SmartArcSetBase<GR>;
818 Arc(int _id) : id(_id) {}
822 Arc(Invalid) : id(-1) {}
823 bool operator==(const Arc& arc) const { return id == arc.id; }
824 bool operator!=(const Arc& arc) const { return id != arc.id; }
825 bool operator<(const Arc& arc) const { return id < arc.id; }
830 Arc addArc(const Node& u, const Node& v) {
832 arcs.push_back(ArcT());
833 arcs[n].next_in = (*_nodes)[v].first_in;
834 (*_nodes)[v].first_in = n;
835 arcs[n].next_out = (*_nodes)[u].first_out;
836 (*_nodes)[u].first_out = n;
844 for (first(node); node != INVALID; next(node)) {
845 (*_nodes)[node].first_in = -1;
846 (*_nodes)[node].first_out = -1;
851 void first(Node& node) const {
855 void next(Node& node) const {
859 void first(Arc& arc) const {
860 arc.id = arcs.size() - 1;
863 void next(Arc& arc) const {
867 void firstOut(Arc& arc, const Node& node) const {
868 arc.id = (*_nodes)[node].first_out;
871 void nextOut(Arc& arc) const {
872 arc.id = arcs[arc.id].next_out;
875 void firstIn(Arc& arc, const Node& node) const {
876 arc.id = (*_nodes)[node].first_in;
879 void nextIn(Arc& arc) const {
880 arc.id = arcs[arc.id].next_in;
883 int id(const Node& node) const { return _graph->id(node); }
884 int id(const Arc& arc) const { return arc.id; }
886 Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
887 Arc arcFromId(int ix) const { return Arc(ix); }
889 int maxNodeId() const { return _graph->maxNodeId(); };
890 int maxArcId() const { return arcs.size() - 1; }
892 Node source(const Arc& arc) const { return arcs[arc.id].source;}
893 Node target(const Arc& arc) const { return arcs[arc.id].target;}
895 typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
897 NodeNotifier& notifier(Node) const {
898 return _graph->notifier(Node());
901 template <typename V>
902 class NodeMap : public GR::template NodeMap<V> {
905 typedef typename GR::template NodeMap<V> Parent;
907 explicit NodeMap(const SmartArcSetBase<GR>& arcset)
908 : Parent(*arcset._graph) { }
910 NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
911 : Parent(*arcset._graph, value) { }
913 NodeMap& operator=(const NodeMap& cmap) {
914 return operator=<NodeMap>(cmap);
917 template <typename CMap>
918 NodeMap& operator=(const CMap& cmap) {
919 Parent::operator=(cmap);
927 /// \ingroup semi_adaptors
929 /// \brief Digraph using a node set of another digraph or graph and
932 /// This structure can be used to establish another directed graph
933 /// over a node set of an existing one. This class uses the same
934 /// Node type as the underlying graph, and each valid node of the
935 /// original graph is valid in this arc set, therefore the node
936 /// objects of the original graph can be used directly with this
937 /// class. The node handling functions (id handling, observing, and
938 /// iterators) works equivalently as in the original graph.
940 /// \param GR The type of the graph which shares its node set with
941 /// this class. Its interface must conform to the
942 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
945 /// This implementation is slightly faster than the \c ListArcSet,
946 /// because it uses continuous storage for arcs and it uses just
947 /// single-linked lists for enumerate outgoing and incoming
948 /// arcs. Therefore the arcs cannot be erased from the arc sets.
950 /// \warning If a node is erased from the underlying graph and this
951 /// node is the source or target of one arc in the arc set, then
952 /// the arc set is invalidated, and it cannot be used anymore. The
953 /// validity can be checked with the \c valid() member function.
955 /// This class is fully conform to the \ref concepts::Digraph
956 /// "Digraph" concept.
957 template <typename GR>
958 class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
962 typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
964 typedef typename Parent::Node Node;
965 typedef typename Parent::Arc Arc;
971 typedef typename Parent::NodesImplBase NodesImplBase;
973 void eraseNode(const Node& node) {
974 if (typename Parent::InArcIt(*this, node) == INVALID &&
975 typename Parent::OutArcIt(*this, node) == INVALID) {
978 throw typename NodesImplBase::Notifier::ImmediateDetach();
985 class NodesImpl : public NodesImplBase {
987 typedef NodesImplBase Parent;
989 NodesImpl(const GR& graph, SmartArcSet& arcset)
990 : Parent(graph), _arcset(arcset) {}
992 virtual ~NodesImpl() {}
994 bool attached() const {
995 return Parent::attached();
1000 virtual void erase(const Node& node) {
1002 _arcset.eraseNode(node);
1003 Parent::erase(node);
1004 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1009 virtual void erase(const std::vector<Node>& nodes) {
1011 for (int i = 0; i < int(nodes.size()); ++i) {
1012 _arcset.eraseNode(nodes[i]);
1014 Parent::erase(nodes);
1015 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1020 virtual void clear() {
1021 _arcset.clearNodes();
1026 SmartArcSet& _arcset;
1033 /// \brief Constructor of the ArcSet.
1035 /// Constructor of the ArcSet.
1036 SmartArcSet(const GR& graph) : _nodes(graph, *this) {
1037 Parent::initalize(graph, _nodes);
1040 /// \brief Add a new arc to the digraph.
1042 /// Add a new arc to the digraph with source node \c s
1043 /// and target node \c t.
1044 /// \return the new arc.
1045 Arc addArc(const Node& s, const Node& t) {
1046 return Parent::addArc(s, t);
1049 /// \brief Validity check
1051 /// This functions gives back false if the ArcSet is
1052 /// invalidated. It occurs when a node in the underlying graph is
1053 /// erased and it is not isolated in the ArcSet.
1054 bool valid() const {
1055 return _nodes.attached();
1061 template <typename GR>
1062 class SmartEdgeSetBase {
1066 typedef typename GR::Node Node;
1067 typedef typename GR::NodeIt NodeIt;
1073 NodeT() : first_out(-1) {}
1076 typedef typename ItemSetTraits<GR, Node>::
1077 template Map<NodeT>::Type NodesImplBase;
1079 NodesImplBase* _nodes;
1087 std::vector<ArcT> arcs;
1091 void initalize(const GR& graph, NodesImplBase& nodes) {
1099 friend class SmartEdgeSetBase;
1103 explicit Edge(int _id) { id = _id;}
1107 Edge (Invalid) { id = -1; }
1108 bool operator==(const Edge& arc) const {return id == arc.id;}
1109 bool operator!=(const Edge& arc) const {return id != arc.id;}
1110 bool operator<(const Edge& arc) const {return id < arc.id;}
1114 friend class SmartEdgeSetBase;
1116 Arc(int _id) : id(_id) {}
1119 operator Edge() const { return edgeFromId(id / 2); }
1122 Arc(Invalid) : id(-1) {}
1123 bool operator==(const Arc& arc) const { return id == arc.id; }
1124 bool operator!=(const Arc& arc) const { return id != arc.id; }
1125 bool operator<(const Arc& arc) const { return id < arc.id; }
1128 SmartEdgeSetBase() {}
1130 Edge addEdge(const Node& u, const Node& v) {
1131 int n = arcs.size();
1132 arcs.push_back(ArcT());
1133 arcs.push_back(ArcT());
1136 arcs[n | 1].target = v;
1138 arcs[n].next_out = (*_nodes)[v].first_out;
1139 (*_nodes)[v].first_out = n;
1141 arcs[n | 1].next_out = (*_nodes)[u].first_out;
1142 (*_nodes)[u].first_out = (n | 1);
1149 for (first(node); node != INVALID; next(node)) {
1150 (*_nodes)[node].first_out = -1;
1155 void first(Node& node) const {
1156 _graph->first(node);
1159 void next(Node& node) const {
1163 void first(Arc& arc) const {
1164 arc.id = arcs.size() - 1;
1167 void next(Arc& arc) const {
1171 void first(Edge& arc) const {
1172 arc.id = arcs.size() / 2 - 1;
1175 void next(Edge& arc) const {
1179 void firstOut(Arc& arc, const Node& node) const {
1180 arc.id = (*_nodes)[node].first_out;
1183 void nextOut(Arc& arc) const {
1184 arc.id = arcs[arc.id].next_out;
1187 void firstIn(Arc& arc, const Node& node) const {
1188 arc.id = (((*_nodes)[node].first_out) ^ 1);
1189 if (arc.id == -2) arc.id = -1;
1192 void nextIn(Arc& arc) const {
1193 arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
1194 if (arc.id == -2) arc.id = -1;
1197 void firstInc(Edge &arc, bool& dir, const Node& node) const {
1198 int de = (*_nodes)[node].first_out;
1201 dir = ((de & 1) == 1);
1207 void nextInc(Edge &arc, bool& dir) const {
1208 int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
1211 dir = ((de & 1) == 1);
1218 static bool direction(Arc arc) {
1219 return (arc.id & 1) == 1;
1222 static Arc direct(Edge edge, bool dir) {
1223 return Arc(edge.id * 2 + (dir ? 1 : 0));
1226 int id(Node node) const { return _graph->id(node); }
1227 static int id(Arc arc) { return arc.id; }
1228 static int id(Edge arc) { return arc.id; }
1230 Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
1231 static Arc arcFromId(int id) { return Arc(id); }
1232 static Edge edgeFromId(int id) { return Edge(id);}
1234 int maxNodeId() const { return _graph->maxNodeId(); };
1235 int maxArcId() const { return arcs.size() - 1; }
1236 int maxEdgeId() const { return arcs.size() / 2 - 1; }
1238 Node source(Arc e) const { return arcs[e.id ^ 1].target; }
1239 Node target(Arc e) const { return arcs[e.id].target; }
1241 Node u(Edge e) const { return arcs[2 * e.id].target; }
1242 Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
1244 typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
1246 NodeNotifier& notifier(Node) const {
1247 return _graph->notifier(Node());
1250 template <typename V>
1251 class NodeMap : public GR::template NodeMap<V> {
1254 typedef typename GR::template NodeMap<V> Parent;
1256 explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
1257 : Parent(*arcset._graph) { }
1259 NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
1260 : Parent(*arcset._graph, value) { }
1262 NodeMap& operator=(const NodeMap& cmap) {
1263 return operator=<NodeMap>(cmap);
1266 template <typename CMap>
1267 NodeMap& operator=(const CMap& cmap) {
1268 Parent::operator=(cmap);
1275 /// \ingroup semi_adaptors
1277 /// \brief Graph using a node set of another digraph or graph and an
1280 /// This structure can be used to establish another graph over a
1281 /// node set of an existing one. This class uses the same Node type
1282 /// as the underlying graph, and each valid node of the original
1283 /// graph is valid in this arc set, therefore the node objects of
1284 /// the original graph can be used directly with this class. The
1285 /// node handling functions (id handling, observing, and iterators)
1286 /// works equivalently as in the original graph.
1288 /// \param GR The type of the graph which shares its node set
1289 /// with this class. Its interface must conform to the
1290 /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
1293 /// This implementation is slightly faster than the \c ListEdgeSet,
1294 /// because it uses continuous storage for edges and it uses just
1295 /// single-linked lists for enumerate incident edges. Therefore the
1296 /// edges cannot be erased from the edge sets.
1298 /// \warning If a node is erased from the underlying graph and this
1299 /// node is incident to one edge in the edge set, then the edge set
1300 /// is invalidated, and it cannot be used anymore. The validity can
1301 /// be checked with the \c valid() member function.
1303 /// This class is fully conform to the \ref concepts::Graph
1304 /// "Graph" concept.
1305 template <typename GR>
1306 class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
1310 typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
1312 typedef typename Parent::Node Node;
1313 typedef typename Parent::Arc Arc;
1314 typedef typename Parent::Edge Edge;
1320 typedef typename Parent::NodesImplBase NodesImplBase;
1322 void eraseNode(const Node& node) {
1323 if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
1326 throw typename NodesImplBase::Notifier::ImmediateDetach();
1333 class NodesImpl : public NodesImplBase {
1335 typedef NodesImplBase Parent;
1337 NodesImpl(const GR& graph, SmartEdgeSet& arcset)
1338 : Parent(graph), _arcset(arcset) {}
1340 virtual ~NodesImpl() {}
1342 bool attached() const {
1343 return Parent::attached();
1348 virtual void erase(const Node& node) {
1350 _arcset.eraseNode(node);
1351 Parent::erase(node);
1352 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1357 virtual void erase(const std::vector<Node>& nodes) {
1359 for (int i = 0; i < int(nodes.size()); ++i) {
1360 _arcset.eraseNode(nodes[i]);
1362 Parent::erase(nodes);
1363 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1368 virtual void clear() {
1369 _arcset.clearNodes();
1374 SmartEdgeSet& _arcset;
1381 /// \brief Constructor of the EdgeSet.
1383 /// Constructor of the EdgeSet.
1384 SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
1385 Parent::initalize(graph, _nodes);
1388 /// \brief Add a new edge to the graph.
1390 /// Add a new edge to the graph with node \c u
1391 /// and node \c v endpoints.
1392 /// \return the new edge.
1393 Edge addEdge(const Node& u, const Node& v) {
1394 return Parent::addEdge(u, v);
1397 /// \brief Validity check
1399 /// This functions gives back false if the EdgeSet is
1400 /// invalidated. It occurs when a node in the underlying graph is
1401 /// erased and it is not isolated in the EdgeSet.
1402 bool valid() const {
1403 return _nodes.attached();