Eulerian path
An Eulerian path is a trail in a finite undirected graph that visits every edge exactly once, possibly revisiting vertices along the way.[1] If the path is closed—meaning it starts and ends at the same vertex—it is known as an Eulerian circuit or Eulerian cycle.[2] This concept forms a foundational element of graph theory, a branch of mathematics that studies networks of vertices connected by edges.[3]
The notion of an Eulerian path originated in 1736 with Leonhard Euler's solution to the Seven Bridges of Königsberg problem, widely regarded as the birth of graph theory.[4] In this historical puzzle, the city of Königsberg (now Kaliningrad) featured seven bridges spanning the Pregel River and its islands; residents sought a walk that crossed each bridge exactly once and returned to the starting point.[5] Euler modeled the problem as a graph with four vertices (landmasses) and seven edges (bridges), proving no such closed path existed because the graph had more than two vertices of odd degree.[6]
For an undirected connected graph to possess an Eulerian path, it must have exactly zero or two vertices of odd degree; the former case yields an Eulerian circuit, while the latter starts and ends at the odd-degree vertices.[7] Euler's original 1736 paper, "Solutio problematis ad geometriam situs pertinentis," provided the first general criteria for such paths in both undirected and directed graphs, establishing theorems that remain central to the field.[4] These ideas have since influenced diverse applications, including network routing, DNA sequencing, and optimization problems in computer science.[8]
Fundamentals
Definition
In graph theory, a graph is a mathematical structure consisting of a set of vertices (also called nodes or points) connected by edges (links or lines), which may or may not allow multiple edges between the same pair of vertices or self-loops.[9] A path is a sequence of distinct vertices connected by edges, while a trail is a walk in which no edge is repeated (though vertices may be revisited), and a circuit is a closed trail that starts and ends at the same vertex.[9]
An Eulerian path in a graph is a trail that visits every edge exactly once, allowing revisits to vertices as needed.[9] This concept differs fundamentally from a Hamiltonian path, which requires visiting every vertex exactly once but places no restrictions on edges beyond connectivity.[10] An Eulerian circuit, also known as an Eulerian cycle, is a special case of an Eulerian path that is closed, meaning it starts and ends at the same vertex while still traversing each edge exactly once.[11]
The notion of an Eulerian path originated from the historical Seven Bridges of Königsberg problem, posed in the 18th century, where the goal was to find a walk crossing each of the city's seven bridges exactly once.[5] In 1735, Leonhard Euler proved that no such path exists in the corresponding graph, as it features four vertices of odd degree, laying the foundational insight for Eulerian paths in graph theory.[4]
Basic Terminology
In graph theory, a walk is a sequence of vertices and edges in a graph where each edge connects consecutive vertices in the sequence, allowing repetitions of both vertices and edges.[12] A trail is a walk in which no edge is repeated.[12] A path is a trail in which no vertex is repeated.[12] A circuit is a closed trail, meaning it starts and ends at the same vertex with no repeated edges.[12] An Eulerian path, for example, is a special type of trail that traverses every edge in the graph exactly once.[12]
A graph is connected if there exists a path between every pair of its vertices; otherwise, it is disconnected.[12] Graphs in foundational graph theory are typically assumed to be finite, consisting of a finite number of vertices and edges, though infinite graphs—those with infinitely many vertices or edges—are studied in advanced contexts but require careful handling of connectivity and traversal properties.[13]
The degree of a vertex in an undirected graph is the number of edges incident to it, with a loop at the vertex contributing two to its degree.[12] Vertices are classified by degree parity: a vertex has even degree if its degree is even and odd degree if odd, a distinction critical for analyzing traversability in graphs.[12]
A multigraph generalizes a simple graph by permitting multiple edges between the same pair of vertices and loops (edges connecting a vertex to itself), which is essential in Eulerian contexts to model scenarios like multiple bridges between landmasses without assuming uniqueness of connections.[12]
Properties
In Undirected Graphs
In undirected graphs, an Eulerian circuit exists if and only if the graph is connected and every vertex has even degree. This condition ensures that a closed trail traversing each edge exactly once can be formed, returning to the starting vertex. The theorem originates from Leonhard Euler's foundational work on the Königsberg bridge problem, where he established that traversability depends on vertex degrees.[14]
For an Eulerian path (which may be open), the graph must be connected and have exactly zero or two vertices of odd degree; in the latter case, the path starts at one odd-degree vertex and ends at the other. If all degrees are even, the path is closed (a circuit); otherwise, the two odd-degree vertices serve as the endpoints. This criterion follows from parity considerations: each intermediate vertex in a trail must have even degree in the remaining graph to allow entry and exit via unused edges.
A sketch of the proof for these theorems relies on constructing trails and using degree parity. For the circuit case, begin at any vertex and extend a trail as far as possible until stuck at a vertex v with unused incident edges; since all degrees are even, v must still have even degree in the unused edges, allowing a cycle to be found and spliced into the trail. Repeating this removes all edges, yielding the circuit. The path case extends this by starting at an odd-degree vertex if applicable, ensuring the trail ends at the other odd-degree vertex after exhausting edges. Conversely, if an Eulerian trail exists, removing its edges leaves even degrees at all vertices except possibly the endpoints, confirming the degree conditions.
A representative example is the complete graph K_n, where each vertex has degree n-1. Thus, K_n admits an Eulerian circuit precisely when n is odd, as all degrees are then even. For disconnected graphs, an Eulerian path or circuit exists only if all edges lie in a single connected component (ignoring isolated vertices, which have no edges and thus do not affect traversability), and that component satisfies the degree conditions above.
In Directed Graphs
In directed graphs, the conditions for the existence of an Eulerian circuit differ from those in undirected graphs primarily due to the orientation of edges, requiring balance between incoming and outgoing edges at each vertex along with appropriate connectivity. A directed graph has an Eulerian circuit if and only if every vertex has equal in-degree and out-degree, and all vertices with nonzero degree belong to a single strongly connected component.
For an Eulerian path that is not closed, the degree conditions are relaxed at exactly two vertices: the graph has an Eulerian path if and only if all vertices with nonzero degree belong to a single connected component of the underlying undirected graph, exactly one vertex s (the start) has out-degree equal to in-degree plus one, exactly one vertex t (the end) has in-degree equal to out-degree plus one, and all other vertices have equal in-degree and out-degree.[15]
The proof of these theorems proceeds by constructing a maximal directed trail and using the degree balance to ensure it can be extended or closed appropriately. If the conditions hold, begin at a vertex with unused outgoing edges (or the designated start for paths) and follow directed edges until no unused outgoing edge remains at the current vertex; due to equal in- and out-degrees (or the specified imbalance), the trail ends at the starting vertex for circuits or the designated end for paths. If unused edges remain elsewhere, the connectivity properties—strong connectivity for circuits and weak connectivity (with start at s) for paths—guarantee the ability to find a directed subtrail using only unused edges starting from some vertex on the current trail, which is then inserted into the trail. Repeating this splicing process exhausts all edges, yielding the Eulerian tour. This construction mirrors the undirected case but enforces directionality in trail formation and cycle insertion to respect edge orientations.[16][17]
Strong connectivity is crucial, as it ensures directed paths exist between any pair of vertices, allowing the traversal to reach and incorporate all edges without needing to reverse directions. In contrast, mere weak connectivity—where the underlying undirected graph is connected—may permit balanced degrees but fail to provide the necessary directed routes for an Eulerian circuit; for instance, two vertices connected by edges in opposite directions but no cycle would violate strong connectivity despite weak connectivity and balanced degrees.[18]
A simple example is a directed cycle graph on n \geq 3 vertices, where each vertex has in-degree and out-degree 1; it is strongly connected and thus admits an Eulerian circuit traversing the cycle once. For an Eulerian path, consider a directed path graph on n \geq 2 vertices, where the start vertex has out-degree 1 and in-degree 0, the end has in-degree 1 and out-degree 0, and intermediate vertices have both degrees 1; the underlying undirected graph is connected (i.e., the graph is weakly connected), confirming the existence of the Eulerian path along the sequence. Tournament graphs, which are complete directed graphs, provide another illustration: a strong tournament (strongly connected) with all in-degrees equal to out-degrees admits an Eulerian circuit, as seen in regular tournaments of odd order.[19]
Construction Algorithms
Fleury's Algorithm
Fleury's algorithm provides a straightforward recursive method for constructing an Eulerian path in an undirected graph that meets the existence conditions, such as having exactly zero or two vertices of odd degree. Developed by French mathematician Pierre-Henry Fleury in 1883, the algorithm proceeds by building the path incrementally while adhering to a key rule to ensure connectivity of the remaining graph.[20][21]
Central to the algorithm is the concept of a bridge, defined as an edge in a connected graph whose removal increases the number of connected components. During traversal, the algorithm avoids crossing a bridge in the subgraph induced by the unused edges unless no alternative non-bridge edge is available from the current vertex. This "bridge-avoidance" rule prevents prematurely disconnecting the graph, ensuring that all edges can be traversed.[21]
The procedure begins at a vertex of odd degree if an Eulerian path (but not circuit) is sought, or at any vertex otherwise. From the current vertex, select an unused adjacent edge that is not a bridge in the subgraph of remaining unused edges, traverse it to the next vertex, and mark the edge as used. If the only available edges are bridges, select one and proceed. Recur until no unused edges remain, then reverse the path to obtain the Eulerian path in the correct order. For an Eulerian circuit, the process naturally closes upon returning to the start.[22][21]
The following pseudocode outlines the recursive implementation, assuming the graph is represented as an adjacency list and edges are tracked for usage:
function Fleury(graph G, start_vertex v):
path = []
def dfs(current):
while there are unused edges from current:
# Prefer non-bridge edge if available
selected_e = None
selected_w = None
for each unused edge e from current to neighbor w:
if not is_bridge(G_unused, e):
selected_e = e
selected_w = w
break
if selected_e is None and there are unused edges from current:
# Take a bridge if no non-bridge available
selected_e = first unused edge from current to some w
selected_w = w
if selected_e is not None:
mark selected_e as used
dfs(selected_w)
path.append(selected_e)
dfs(v)
path.reverse()
return path
# Helper: is_bridge checks connectivity after temporary removal via DFS/BFS on unused edges
function Fleury(graph G, start_vertex v):
path = []
def dfs(current):
while there are unused edges from current:
# Prefer non-bridge edge if available
selected_e = None
selected_w = None
for each unused edge e from current to neighbor w:
if not is_bridge(G_unused, e):
selected_e = e
selected_w = w
break
if selected_e is None and there are unused edges from current:
# Take a bridge if no non-bridge available
selected_e = first unused edge from current to some w
selected_w = w
if selected_e is not None:
mark selected_e as used
dfs(selected_w)
path.append(selected_e)
dfs(v)
path.reverse()
return path
# Helper: is_bridge checks connectivity after temporary removal via DFS/BFS on unused edges
To initiate, call Fleury on the full graph starting from an appropriate vertex; the full path is assembled by concatenating recursive results in reverse. Bridge checks can be performed by temporarily removing the edge and verifying connectivity via DFS or BFS on the unused subgraph.[23][21]
The time complexity of Fleury's algorithm is O(E^2), where E is the number of edges, arising from O(E) traversal steps, each potentially requiring O(E) time to check for bridges via connectivity queries.[24]
Consider a small multigraph with vertices A, B, and C, and edges: two between A and B (labeled e1, e2), two between B and C (e3, e4), and one between A and C (e5). Degrees are odd at A (3) and C (3), even at B (4), so an Eulerian path exists from A to C. Start at A. From A, possible edges are e1 to B or e5 to C. Checking the unused subgraph, e5 is a bridge (removing it disconnects C from A-B), so prefer e1 to B (non-bridge). Traverse e1 to B; now unused: e2 (A-B), e3/e4 (B-C), e5 (A-C). From B, e2 leads back to A (non-bridge), e3/e4 to C (non-bridge). Suppose take e3 to C. From C, only e4 back to B (but e4 unused? Wait, e4 still unused, but from C now only e5? No: current unused after e1 and e3: e2(A-B), e4(B-C), e5(A-C). From C, no direct unused except via previous, but since at C after e3, unused from C: e4 (C-B), e5 (C-A). Check e4: removing e4 from unused {e2,e4,e5} keeps connected (A-B-C via e2,e5), so non-bridge; but e4 goes to B. Traverse e4 to B. Now at B, unused: e2(A-B), e5(A-C). From B, only e2 to A (non-bridge). Traverse e2 to A. Now at A, unused: e5(A-C). e5 is now a bridge in remaining (single edge), so traverse to C. Path: A-e1-B-e3-C-e4-B-e2-A-e5-C, covering all edges.[25]
Hierholzer's Algorithm
Hierholzer's algorithm, developed by German mathematician Carl Hierholzer and published posthumously in 1873, provides an efficient method for constructing an Eulerian circuit in a connected undirected graph where every vertex has even degree, predating Fleury's algorithm by several years.[26] The core idea involves decomposing the graph into edge-disjoint cycles and then splicing these cycles together to form a single Eulerian tour, ensuring all edges are traversed exactly once. This approach avoids explicit checks for bridges, relying instead on the graph's Eulerian properties to guarantee success.
The algorithm proceeds iteratively as follows: Select a starting vertex with unused edges and traverse arbitrary unused edges to form an initial cycle until returning to the start. Then, identify any vertex along this cycle that still has unused incident edges, and from that vertex, construct a sub-cycle using the remaining edges in a similar manner. Insert this sub-cycle into the original cycle at the chosen vertex by splicing—effectively breaking the original cycle at that point and combining the paths. Repeat this process recursively or iteratively until no unused edges remain, yielding the complete Eulerian circuit.
For graphs with an Eulerian path (exactly two vertices of odd degree), the algorithm adapts by starting at one odd-degree vertex; the process remains the same, but the final output is an open path ending at the other odd-degree vertex rather than a closed circuit. An efficient iterative implementation uses a stack to simulate the traversal without recursion, avoiding stack overflow in large graphs.
The following pseudocode outlines the stack-based version for an undirected multigraph represented as an adjacency list, where edges are removed as they are used:
function findEulerianCircuit(graph, start):
circuit = empty list
stack = empty stack
stack.push(start)
while stack is not empty:
current = stack.top()
if graph[current] has unused edges:
next = pick and remove an unused edge from current to some neighbor w
stack.push(w)
else:
circuit.append(stack.pop())
reverse the circuit
return circuit
function findEulerianCircuit(graph, start):
circuit = empty list
stack = empty stack
stack.push(start)
while stack is not empty:
current = stack.top()
if graph[current] has unused edges:
next = pick and remove an unused edge from current to some neighbor w
stack.push(w)
else:
circuit.append(stack.pop())
reverse the circuit
return circuit
This implementation traverses each edge exactly once during construction and processes vertices proportional to their degrees, achieving O(E) time complexity, where E is the number of edges.
To illustrate, consider a simplified Königsberg-like graph with four vertices A, B, C, D and seven edges forming odd degrees at all vertices (two bridges between A-B, A-C, A-D, B-D, C-D). Assuming the graph is checked for Eulerian properties beforehand, the algorithm would fail to cover all edges in a single tour if started arbitrarily, as sub-tours would leave residual unused edges at odd-degree vertices, confirming the absence of an Eulerian path or circuit. In contrast, modifying the graph to even degrees (e.g., adding a third edge between B and C) allows the algorithm to successfully construct a full tour by finding and splicing cycles, such as an initial A-B-D-A cycle followed by insertions for remaining edges.
Counting Eulerian Circuits
Computational Complexity
The problem of counting the number of distinct Eulerian circuits in a given Eulerian graph, where circuits are considered equivalent up to choice of starting vertex, is a fundamental enumeration task in graph theory. This count captures the structural multiplicity of edge traversals that cover every edge exactly once and return to the origin, providing insights into the graph's connectivity and symmetry beyond mere existence checks.
In undirected graphs, exact counting of Eulerian circuits is #P-complete, even when restricted to 4-regular graphs. The hardness follows from a parsimonious reduction from the #P-complete problem of counting Hamiltonian cycles in cubic graphs, combined with modular arithmetic techniques to preserve counts modulo primes. This result implies that no polynomial-time algorithm exists unless P = #P, underscoring the challenge of enumeration compared to the polynomial-time decision problem of existence.[27]
For directed graphs, the situation differs markedly: the number of Eulerian circuits can be computed exactly in polynomial time using the BEST theorem, which expresses the count as the product of vertex-specific factors involving indegrees and the number of arborescences (directed spanning trees) rooted at a vertex, computable via the matrix-tree theorem. This connection to Laplacian determinants enables efficient evaluation, typically in O(n^3) time for n vertices, highlighting a tractable case amid broader hardness.[28][29]
No fully polynomial randomized approximation scheme (FPRAS) is known for counting Eulerian circuits in general undirected graphs, consistent with the #P-completeness; however, randomized approximation algorithms exist for related problems like counting Eulerian orientations, achieving multiplicative approximations in polynomial time with high probability. For sparse graphs or those with bounded treewidth, exact counting algorithms run in polynomial time via dynamic programming over graph decompositions, offering practical bounds for restricted sparsity. Exact polynomial-time methods exist for generalized series-parallel graphs, but general approximations remain elusive without further structural assumptions.[30][31][32][33]
Special Graph Cases
The BEST theorem provides an exact method for counting the number of Eulerian circuits in connected directed Eulerian graphs, where every vertex has equal in-degree and out-degree. The theorem states that the number of such circuits, denoted ec(G), is given by
ec(G) = t(G) \prod_{v \in V(G)} (\deg^+(v) - 1)!
where \deg^+(v) is the out-degree of vertex v, and t(G) is the number of spanning arborescences of G rooted at any fixed vertex (this value is independent of the choice of root due to degree balance).[34] The spanning arborescences can be computed using the matrix-tree theorem applied to the Laplacian of the graph.
This formula derives from a decomposition of Eulerian circuits into a rooted spanning arborescence (providing the tree structure) and cycles attached to it, with the factorial terms accounting for the permutations of outgoing edges at each vertex excluding the tree edge. The product over factorials captures the local ordering choices, while t(G) enumerates the global tree configurations compatible with the circuit.[34]
For undirected Eulerian graphs, no universal closed-form formula analogous to the BEST theorem exists, as counting is #P-complete in general, but exact computations are feasible for specific families where structural properties simplify the evaluation, often by summing over Eulerian orientations or using recursive decompositions. In complete graphs K_n with n odd (ensuring even degrees), explicit formulas involve recursive functions counting compatible edge orderings; for instance, the triangle K_3 has exactly 2 Eulerian circuits, corresponding to the two possible traversals of its edges.[35] For 4-regular graphs, exact counting remains challenging but is tractable in subclasses like those with bounded treewidth via dynamic programming. Similarly, for generalized series-parallel graphs, polynomial-time algorithms enable exact counts using decompositions, though the problem is #P-complete for general planar graphs.[33]
Counting Eulerian circuits in infinite graphs falls outside the scope of finite exact formulas like the BEST theorem, as the infinite edge set precludes a well-defined finite traversal; such cases are addressed in generalizations to infinite structures.
Variants and Generalizations
Mixed Graphs
A mixed graph is a graph that features both undirected edges and directed arcs between vertices. An Eulerian path in a mixed graph is a trail that visits every edge and arc exactly once, respecting the orientation of arcs while allowing undirected edges to be traversed in either direction.
The conditions for the existence of an Eulerian path or circuit in mixed graphs generalize those for pure undirected and directed graphs by accounting for the flexibility in orienting undirected edges to balance degree imbalances caused by the directed arcs. A necessary and sufficient condition for a mixed graph to have an Eulerian circuit, due to Ford and Fulkerson (1962), is that every vertex has even degree (counting undirected edges as contributing to degree without direction), and for every subset of vertices S, the absolute difference between the number of directed arcs leaving S and entering S is at most the number of undirected edges incident to S. The graph must also be weakly connected.[36] This ensures there exists an orientation of the undirected edges such that the resulting directed graph is balanced (equal in- and out-degrees at every vertex) and strongly connected, admitting an Eulerian circuit.
In cases where the directed subgraph has imbalances, the local conditions at each vertex v provide a starting point: define the deficit \delta(v) = \deg^+(v) - \deg^-(v), where \deg^+(v) and \deg^-(v) are the out-degree and in-degree from directed arcs. A balancing orientation exists locally if |\delta(v)| \leq d_u(v) (undirected degree) and \delta(v) \equiv d_u(v) \pmod{2} for every v. However, global conditions like the subset balance are needed to ensure strong connectivity in the oriented graph. These can be checked using maximum flow or matching algorithms.[37]
For an Eulerian path (not necessarily closed), the conditions are analogous but allow for exactly one vertex with effective surplus +1 (start) and one with -1 (end) in the oriented degrees, with the graph weakly connected and the subset condition adjusted accordingly for semi-balance.[38] (Digraphs: Theory, Algorithms and Applications)
To construct an Eulerian path or circuit, Hierholzer's algorithm can be adapted by first computing a balancing and connectivity-preserving orientation of the undirected edges (using a flow network to model required adjustments, with undirected edges as bidirectional unit capacities). The resulting fully directed graph, being strongly connected (or weakly for paths) with balanced degrees, then admits the standard Hierholzer's algorithm: start at a vertex, perform a tour until stuck, then splice in sub-tours from unused incident arcs at visited vertices until all arcs are traversed.
As an example, consider a hybrid road network where some streets are one-way (directed arcs) with imbalances adjustable by two-way streets (undirected edges), satisfying the local and global conditions; an Eulerian circuit exists, allowing a patrol route that covers every street segment exactly once.
Infinite Graphs
In infinite graphs, the concept of an Eulerian path is extended to account for non-terminating structures. An Eulerian ray is defined as a one-way infinite trail—a sequence of vertices and edges where no edge is repeated—that traverses every edge of the graph exactly once. Similarly, an Eulerian double ray is a two-way infinite trail covering all edges exactly once, analogous to an Eulerian circuit in finite graphs. These definitions apply particularly to locally finite graphs, where every vertex has finite degree, ensuring the trails can be constructed without encountering vertices of infinite degree.[39]
A fundamental result characterizing the existence of such paths in connected infinite graphs is the theorem of Erdős, Grünwald, and Weiszfeld (1936), which generalizes Euler's theorem for finite graphs to the infinite case. For locally finite connected graphs, this implies that an Eulerian double ray exists if and only if every vertex has even degree, while an Eulerian ray exists if and only if there is exactly one vertex of odd degree (with the ray starting at that vertex). This can be viewed as an extension of Veblen's theorem on cycle decompositions, where double rays play the role of infinite cycles in the topological cycle space of the graph. If there are more than one odd-degree vertex, no single Eulerian ray or double ray covers all edges, though the graph may admit decompositions into multiple such structures.[40]
Examples illustrate these conditions clearly. The infinite ray graph, consisting of vertices v_0, v_1, v_2, \dots with edges \{v_i, v_{i+1}\} for i \geq 0, has degree 1 at v_0 (odd) and degree 2 at all other vertices (even); it admits an Eulerian ray starting at v_0. In contrast, the infinite double ray (a two-way infinite path) has all degrees 2 (even) and possesses an Eulerian double ray traversing the entire structure. The infinite ladder graph, however, with vertices on two parallel rays connected by rungs, has all vertices of degree 3 (odd) and thus lacks an Eulerian ray or double ray.[41]
Modern extensions since 2000 have explored Eulerian structures in more specialized infinite graphs. In hyperbolic graphs—those with thin triangles satisfying the δ-hyperbolicity condition—results on Eulerian maps and spaces address how boundary behavior at infinity affects trail existence, with applications to group actions and compactifications. For instance, Eulerian spaces on locally finite hyperbolic graphs incorporate the Gromov boundary to ensure trails respect hyperbolic geometry without accumulating at ends. Similarly, in random infinite graphs, such as those generated by branching processes or percolation on lattices, probabilistic methods determine the almost-sure existence of Eulerian rays under degree parity conditions, linking to computability questions in algorithmic graph theory. These developments emphasize ray equivalence classes and end-degrees for robust generalizations.[40]
Relation to Bridges
In undirected graphs, the presence of a bridge—an edge whose removal increases the number of connected components—forces any Eulerian path to traverse it exactly once, as bridges lie on no cycles and cannot be revisited without repeating edges. This traversal links the 2-edge-connected components on either side of the bridge, requiring the Eulerian path to complete an Eulerian tour within each component before or after crossing, effectively sequencing the graph's structure along the bridges.[1]
A key theorem establishes that a connected undirected graph admits an Eulerian circuit if and only if every vertex has even degree, which necessarily implies the graph is 2-edge-connected and thus bridgeless. The existence of a bridge would contradict the circuit's requirement to return to the starting vertex, as the circuit could cross the bridge only once but would need to do so an even number of times to balance the traversal of the separated components.[42]
To analyze Eulerian paths in graphs containing bridges, one can use the bridge-block decomposition, where the graph is partitioned into its 2-edge-connected blocks (maximal subgraphs without bridges) connected by the bridges themselves. The resulting bridge-block tree treats blocks as vertices and bridges as edges between them; an Eulerian path in the original graph exists if and only if this tree has at most two vertices of odd degree (corresponding to blocks with odd-degree vertices in the original graph), and the path in the tree dictates the order of traversing blocks and crossing bridges. For instance, consider a graph consisting of two cycles connected by a single bridge: no Eulerian circuit exists due to the bridge, but an Eulerian path starts in one cycle, traverses all its edges, crosses the bridge once, and ends after traversing the second cycle.[43]
Fleury's algorithm explicitly accounts for bridges to ensure the construction of an Eulerian path remains valid. The algorithm proceeds by building the path step by step, preferring non-bridge edges when possible to avoid prematurely disconnecting the remaining graph; only when no alternative exists does it traverse a bridge, guaranteeing that all edges are covered without stranding unused edges in separate components. This bridge rule is crucial for correctness in graphs with bridges, as violating it could leave untraversable subgraphs.[44]
Applications
Route Optimization Problems
The Chinese Postman Problem (CPP), also known as the route inspection problem, involves finding the shortest closed walk in a connected edge-weighted graph that traverses every edge at least once.[45] This problem is closely tied to Eulerian paths, as an optimal solution can be obtained by augmenting the graph with the minimum total length of duplicate edges to render it Eulerian, after which an Eulerian circuit provides the desired tour.[46]
For undirected graphs, the CPP is solved in polynomial time using an algorithm that first identifies all vertices of odd degree.[45] These vertices are then paired via a minimum-cost perfect matching in a complete graph where the edge weights between pairs represent the shortest-path distances in the original graph; the corresponding shortest paths are duplicated to create the augmented Eulerian graph.[46] In the directed case, assuming the graph is strongly connected, the solution balances the in-degree and out-degree imbalances at each vertex by adding a minimum-cost set of arcs, again yielding an Eulerian digraph.[45]
Real-world applications of the CPP in route optimization span logistics and manufacturing, including minimizing distances for postal delivery routes where mail carriers must cover all streets, efficient snow plowing to clear every road segment in urban areas, and optimizing drilling sequences for holes in printed circuit boards (PCBs) to reduce machine travel time.[45][47][48] Such uses date back to the late 20th century, particularly in industrial routing tasks like PCB production.[48]
While the undirected and directed variants of the CPP are polynomially solvable, the mixed CPP—where the graph contains both directed and undirected edges—is NP-hard, complicating exact solutions for hybrid routing scenarios.
Sequence Assembly Problems
In sequence assembly problems, particularly in bioinformatics, Eulerian paths play a central role in reconstructing long DNA sequences from short, overlapping fragments known as reads. This approach leverages de Bruijn graphs, where vertices represent k-mers (substrings of length k from the reads), and directed edges represent (k+1)-mers, connecting two k-mers that overlap by exactly k bases. An Eulerian path in this graph traverses each edge exactly once, effectively reconstructing the original sequence by starting with the initial k-mer and appending the non-overlapping base from each subsequent edge, thereby handling the overlaps inherent in shotgun sequencing data.[49]
The application of this method to shotgun sequencing emerged in the 1990s as a computationally efficient alternative to overlap-layout-consensus strategies, enabling the assembly of large genomes by breaking them into manageable fragments and relying on random overlaps for reconstruction. A seminal formulation was proposed by Idury and Waterman in 1995, who demonstrated how de Bruijn graphs and Eulerian paths could address the fragment assembly problem, particularly for handling coverage and repeats.[50] This technique gained prominence in subsequent de novo genome assemblies using next-generation sequencing technologies, facilitating the integration of millions of short reads into contiguous sequences despite sequencing errors and gaps. For efficient computation of the Eulerian path, Hierholzer's algorithm is commonly employed, as it runs in linear time relative to the number of edges, making it scalable for massive datasets generated by high-throughput sequencing.[51][49]
Variants of the Eulerian path approach adapt to specific challenges, such as error-tolerant assembly for noisy data from single-cell or long-read sequencing, where tools like SPAdes construct multi-sized de Bruijn graphs to correct errors and resolve repeats before path finding. For circular genomes, such as bacterial plasmids, an Eulerian circuit (a closed path) is sought instead, ensuring complete traversal without loose ends. In modern contexts as of 2025, these methods extend to metagenomics, where Eulerian paths in de Bruijn graphs assemble microbial communities from mixed-species samples, as seen in tools like metaSPAdes for scalable reconstruction. Additionally, adaptations using amino acid k-mers enable Eulerian tours for peptide assembly in protein-related tasks, supporting predictions of protein sequences from metagenomic data.[52][53][54]