Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.
Some bugfix in the adaptors
New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
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 #include<lemon/bits/invalid.h>
20 #include<lemon/topology.h>
27 ///This file provides an Euler tour iterator and ways to check
28 ///if a graph is euler.
33 ///Euler iterator for directed graphs.
36 ///This iterator converts to the \c Edge type of the graph and using
37 ///operator ++ it provides an Euler tour of a \e directed
38 ///graph (if there exists).
41 ///if the given graph if Euler (i.e it has only one nontrivial component
42 ///and the in-degree is equal to the out-degree for all nodes),
43 ///the following code will put the edges of \c g
44 ///to the vector \c et according to an
45 ///Euler tour of \c g.
47 /// std::vector<ListGraph::Edge> et;
48 /// for(EulerIt<ListGraph> e(g),e!=INVALID;++e)
51 ///If \c g is not Euler then the resulted tour will not be full or closed.
53 ///\todo Test required
57 typedef typename Graph::Node Node;
58 typedef typename Graph::NodeIt NodeIt;
59 typedef typename Graph::Edge Edge;
60 typedef typename Graph::EdgeIt EdgeIt;
61 typedef typename Graph::OutEdgeIt OutEdgeIt;
62 typedef typename Graph::InEdgeIt InEdgeIt;
65 typename Graph::NodeMap<OutEdgeIt> nedge;
66 std::list<Edge> euler;
72 ///\param _g A directed graph.
73 ///\param start The starting point of the tour. If it is not given
74 /// the tour will start from the first node.
75 EulerIt(const Graph &_g,typename Graph::Node start=INVALID)
78 if(start==INVALID) start=NodeIt(g);
79 for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutEdgeIt(g,n);
80 while(nedge[start]!=INVALID) {
81 euler.push_back(nedge[start]);
82 Node next=g.target(nedge[start]);
89 operator Edge() { return euler.empty()?INVALID:euler.front(); }
90 bool operator==(Invalid) { return euler.empty(); }
91 bool operator!=(Invalid) { return !euler.empty(); }
93 ///Next edge of the tour
94 EulerIt &operator++() {
95 Node s=g.target(euler.front());
97 //This produces a warning.Strange.
98 //std::list<Edge>::iterator next=euler.begin();
99 typename std::list<Edge>::iterator next=euler.begin();
100 while(nedge[s]!=INVALID) {
101 euler.insert(next,nedge[s]);
102 Node n=g.target(nedge[s]);
108 ///Postfix incrementation
110 ///\warning This incrementation
111 ///returns an \c Edge, not an \ref EulerIt, as one may
121 ///Euler iterator for undirected graphs.
123 /// \ingroup topology
124 ///This iterator converts to the \c Edge (or \cUEdge)
125 ///type of the graph and using
126 ///operator ++ it provides an Euler tour of an \undirected
127 ///graph (if there exists).
130 ///if the given graph if Euler (i.e it has only one nontrivial component
131 ///and the degree of each node is even),
132 ///the following code will print the edge IDs according to an
133 ///Euler tour of \c g.
135 /// for(UEulerIt<ListUGraph> e(g),e!=INVALID;++e) {
136 /// std::cout << g.id(UEdge(e)) << std::eol;
139 ///Although the iterator provides an Euler tour of an undirected graph,
140 ///in order to indicate the direction of the tour, UEulerIt
141 ///returns directed edges (that convert to the undirected ones, of course).
143 ///If \c g is not Euler then the resulted tour will not be full or closed.
145 ///\todo Test required
146 template<class Graph>
149 typedef typename Graph::Node Node;
150 typedef typename Graph::NodeIt NodeIt;
151 typedef typename Graph::Edge Edge;
152 typedef typename Graph::EdgeIt EdgeIt;
153 typedef typename Graph::OutEdgeIt OutEdgeIt;
154 typedef typename Graph::InEdgeIt InEdgeIt;
157 typename Graph::NodeMap<OutEdgeIt> nedge;
158 typename Graph::UEdgeMap<bool> visited;
159 std::list<Edge> euler;
165 ///\param _g An undirected graph.
166 ///\param start The starting point of the tour. If it is not given
167 /// the tour will start from the first node.
168 UEulerIt(const Graph &_g,typename Graph::Node start=INVALID)
169 : g(_g), nedge(g), visited(g,false)
171 if(start==INVALID) start=NodeIt(g);
172 for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutEdgeIt(g,n);
173 while(nedge[start]!=INVALID) {
174 euler.push_back(nedge[start]);
175 Node next=g.target(nedge[start]);
177 start=next; while(nedge[start]!=INVALID && visited[nedge[start]]) ++nedge[start];
182 operator Edge() { return euler.empty()?INVALID:euler.front(); }
183 bool operator==(Invalid) { return euler.empty(); }
184 bool operator!=(Invalid) { return !euler.empty(); }
186 ///Next edge of the tour
187 UEulerIt &operator++() {
188 Node s=g.target(euler.front());
190 typename std::list<Edge>::iterator next=euler.begin();
192 while(nedge[s]!=INVALID) {
193 while(nedge[s]!=INVALID && visited[nedge[s]]) ++nedge[s];
194 if(nedge[s]==INVALID) break;
196 euler.insert(next,nedge[s]);
197 Node n=g.target(nedge[s]);
205 ///Postfix incrementation
207 ///\warning This incrementation
208 ///returns an \c Edge, not an \ref UEulerIt, as one may
219 ///Checks if the graph is Euler
221 /// \ingroup topology
222 ///Checks if the graph is Euler. It works for both directed and
223 ///undirected graphs.
224 ///\note By definition, a directed graph is called \e Euler if
225 ///and only if connected and the number of it is incoming and outgoing edges
226 ///are the same for each node.
227 ///Similarly, an undirected graph is called \e Euler if
228 ///and only if it is connected and the number of incident edges is even
229 ///for each node. <em>Therefore, there are graphs which are not Euler, but
230 ///still have an Euler tour</em>.
231 ///\todo Test required
232 template<class Graph>
236 typename enable_if<UndirectedTagIndicator<Graph>,bool>::type
237 euler(const Graph &g)
239 for(typename Graph::NodeIt n(g);n!=INVALID;++n)
240 if(countIncEdges(g,n)%2) return false;
243 template<class Graph>
244 typename disable_if<UndirectedTagIndicator<Graph>,bool>::type
246 euler(const Graph &g)
248 for(typename Graph::NodeIt n(g);n!=INVALID;++n)
249 if(countInEdges(g,n)!=countOutEdges(g,n)) return false;