2 * lemon/topology.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
16 #include<lemon/invalid.h>
23 ///This file provides an Euler tour iterator and ways to check
24 ///if a graph is euler.
29 ///Euler iterator in directed graphs.
32 ///This iterator converts to the \c Edge type of the graph and using
33 ///operator ++ it provides an Euler tour of the graph (if there exists).
36 ///if the given graph if Euler (i.e it has only one nontrivial component
37 ///and the in-degree is equal to the out-degree for all nodes),
38 ///the following code will print the edge IDs according to an
39 ///Euler tour of \c g.
41 /// for(EulerIt<ListGraph> e(g),e!=INVALID;++e) {
42 /// std::cout << g.id(e) << std::eol;
45 ///If \c g is not Euler then the resulted tour will not be full or closed.
46 ///\todo Test required
50 typedef typename Graph::Node Node;
51 typedef typename Graph::NodeIt NodeIt;
52 typedef typename Graph::Edge Edge;
53 typedef typename Graph::EdgeIt EdgeIt;
54 typedef typename Graph::OutEdgeIt OutEdgeIt;
55 typedef typename Graph::InEdgeIt InEdgeIt;
58 typename Graph::NodeMap<OutEdgeIt> nedge;
59 std::list<Edge> euler;
65 ///\param _g A directed graph.
66 ///\param start The starting point of the tour. If it is not given
67 /// the tour will start from the first node.
68 EulerIt(const Graph &_g,typename Graph::Node start=INVALID)
71 if(start==INVALID) start=NodeIt(g);
72 for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutEdgeIt(g,n);
73 while(nedge[start]!=INVALID) {
74 euler.push_back(nedge[start]);
75 Node next=g.target(nedge[start]);
82 operator Edge() { return euler.empty()?INVALID:euler.front(); }
83 bool operator==(Invalid) { return euler.empty(); }
84 bool operator!=(Invalid) { return !euler.empty(); }
86 ///Next edge of the tour
87 EulerIt &operator++() {
88 Node s=g.target(euler.front());
90 //This produces a warning.Strange.
91 //std::list<Edge>::iterator next=euler.begin();
92 typename std::list<Edge>::iterator next=euler.begin();
93 while(nedge[s]!=INVALID) {
94 euler.insert(next,nedge[s]);
95 Node n=g.target(nedge[s]);
101 ///Postfix incrementation
103 ///\warning This incrementation
104 ///returns an \c Edge, not an \ref EulerIt, as one may
114 ///Checks if the graph is Euler
117 ///Checks if the graph is Euler. It works for both directed and
118 ///undirected graphs.
119 ///\todo Test required
120 template<class Graph>
124 typename enable_if<typename Graph::UndirTag,bool>::type
126 euler(const Graph &g)
128 for(typename Graph::NodeIt n(g);n!=INVALID;++n)
129 if(countIncEdges(g,n)%2) return false;
132 template<class Graph>
133 typename disable_if<typename Graph::UndirTag,bool>::type
134 euler(const Graph &g)
136 for(typename Graph::NodeIt n(g);n!=INVALID;++n)
137 if(countInEdges(g,n)!=countOutEdges(g,n)) return false;