<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Muhammad Taaha Tariq</title>
    <description>The latest articles on DEV Community by Muhammad Taaha Tariq (@muhammad_taaha_90438c47f1).</description>
    <link>https://dev.to/muhammad_taaha_90438c47f1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3467248%2Faf847682-780b-449a-a53a-bb2047b0f69f.png</url>
      <title>DEV Community: Muhammad Taaha Tariq</title>
      <link>https://dev.to/muhammad_taaha_90438c47f1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/muhammad_taaha_90438c47f1"/>
    <language>en</language>
    <item>
      <title>Eulerian Paths Explained: From Königsberg to Hierholzer’s Algorithm</title>
      <dc:creator>Muhammad Taaha Tariq</dc:creator>
      <pubDate>Tue, 02 Sep 2025 16:44:03 +0000</pubDate>
      <link>https://dev.to/muhammad_taaha_90438c47f1/eulerian-paths-explained-from-konigsberg-to-hierholzers-algorithm-3p53</link>
      <guid>https://dev.to/muhammad_taaha_90438c47f1/eulerian-paths-explained-from-konigsberg-to-hierholzers-algorithm-3p53</guid>
      <description>&lt;p&gt;Imagine standing on an archipelago, its islands connected by bridges, and facing a seemingly simple question: can you start at one point, cross each bridge exactly once, and return to where you began?&lt;/p&gt;

&lt;p&gt;This puzzle, first posed in the city of &lt;a href="https://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg" rel="noopener noreferrer"&gt;&lt;strong&gt;Königsberg&lt;/strong&gt;&lt;/a&gt;, puzzled mathematicians for years until Euler provided a groundbreaking solution. His work gave birth to what we now call &lt;em&gt;Euler paths&lt;/em&gt; and &lt;em&gt;Euler circuits&lt;/em&gt; — fundamental concepts in graph theory.&lt;/p&gt;

&lt;p&gt;To make the discussion clearer, let's first go over some important definitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Incidence
&lt;/h2&gt;

&lt;p&gt;Considering the same problem, imagine standing on one of the bridges and asking yourself where you can go from there. This idea of a bridge being connected to a landmass is exactly what incidence means.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;  An edge is said to be incident to a vertex if that vertex is one of the edge's endpoints.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;And to get an idea of the number of ways to get to a landmass through bridges is what we commonly refer to as the degree of a vertex or landmass in this context.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt;  &lt;em&gt;Degree&lt;/em&gt; of a vertex refers to the number of edges incident to that vertex, denoted as &lt;strong&gt;deg(v)&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;A loop is counted twice in the degree of a vertex since both its edges are incident to the same vertex.&lt;/p&gt;

&lt;p&gt;In the context of a directed graph, we differentiate between &lt;em&gt;out-degrees&lt;/em&gt; and &lt;em&gt;in-degrees&lt;/em&gt; since the edges offer a unidirectional connection. &lt;strong&gt;In-degree&lt;/strong&gt; of a vertex counts the number of ways to get into that vertex, whereas &lt;strong&gt;Out-degree&lt;/strong&gt; counts the number of ways to get out of that vertex. An important thing to note is that if we were to sum up the in-degrees and out-degrees of all the vertices, then they would be equal. To see why, consider the directed edge as a one-way road; such a road must have a starting point and an endpoint (the vertices), and the same is true for all directed edges.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∑v∈Vdeg⁡+(v)=∑v∈Vdeg⁡−(v)
\sum_{v \in V} \deg^+(v) = \sum_{v \in V} \deg^-(v)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;v&lt;/span&gt;&lt;span class="mrel mtight"&gt;∈&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;de&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mbin mtight"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;v&lt;/span&gt;&lt;span class="mrel mtight"&gt;∈&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;de&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;where &lt;strong&gt;V&lt;/strong&gt; is the vertex set.&lt;/p&gt;

&lt;p&gt;These definitions motivate a theorem, commonly referred to as the first theorem of graph theory or the &lt;a href="https://en.wikipedia.org/wiki/Handshaking_lemma" rel="noopener noreferrer"&gt;&lt;strong&gt;Handshake theorem&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Theorem:&lt;/strong&gt; In an undirected graph, the sum of the degrees of all its vertices is equal to twice the number of edges in the graph.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∑v∈Vdeg⁡(v)=2×∣E∣
\sum_{v \in V} \deg(v) = 2 \times |E|
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;v&lt;/span&gt;&lt;span class="mrel mtight"&gt;∈&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;V&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop"&gt;de&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;span class="mord mathnormal"&gt;E&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;/blockquote&gt;




&lt;p&gt;It follows from the fact that each edge has two endpoints and so, contributes two to the degrees of the graph. This theorem provides insight into the graph structure and allows us to validate graph configuration, and is also useful in graph coloring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eulerian Path/Circuit
&lt;/h2&gt;

&lt;p&gt;To get an intuition of what a path means in graph theory, imagine starting from an island and going around the archipelago, following the bridges, and ending at some island, not necessarily the one you started from (if so, then it is called a circuit), but the bridges and islands can not be revisited. This traversal of islands constitutes a path.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; A &lt;strong&gt;path&lt;/strong&gt; is a sequence of distinct vertices joined by distinct edges, representing a traversal of the graph.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;A circuit is a path whose starting and ending vertices is the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftol4r40ptmf104alptw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftol4r40ptmf104alptw9.png" alt="Illustration of a path"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The path depicted in &lt;em&gt;figure 1&lt;/em&gt; can be thought of as the sequence of vertices A, B, C, E where there is an undirected edge between (aᵢ₋₁, aᵢ) but the directed edges indicate the path traversal.&lt;/p&gt;

&lt;p&gt;Now that we are done with the preliminary definitions and concepts, we turn to the crux of the article.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; An &lt;strong&gt;Euler path&lt;/strong&gt; is a path that visits each edge exactly once.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;An Euler circuit is defined in the same way, with the additional constraint that it must start and end at the same vertex.&lt;/p&gt;

&lt;h3&gt;
  
  
  Existence
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Criteria 1
&lt;/h4&gt;

&lt;p&gt;For an Euler path to exist, the graph must be connected. If it has an isolated subgraph, then such a subgraph must not have any edges. This is because if isolated subgraphs have distinct edges, then any path through the graph can't traverse all of these isolated subgraphs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs2vypw8xkowqbp0fr7p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs2vypw8xkowqbp0fr7p.png" alt="Illustration of criteria 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we start from any bᵢ we can only traverse the bⱼ's where j = 1, 2, 3, 4 vertices and not the (aᵢ, aⱼ) edges. Similarly for aᵢ's.&lt;/p&gt;

&lt;h4&gt;
  
  
  Criteria 2
&lt;/h4&gt;

&lt;p&gt;For a directed graph, the difference between &lt;strong&gt;deg⁺(v)&lt;/strong&gt; and &lt;strong&gt;deg⁻(v)&lt;/strong&gt; must be less than two, that is &lt;strong&gt;|deg⁺(v) - deg⁻(v)| &amp;lt; 2&lt;/strong&gt;, for if it is two or greater, not all the edges can be traversed.&lt;/p&gt;

&lt;p&gt;To see why, consider the case where &lt;strong&gt;deg⁺(v) = 2&lt;/strong&gt; and &lt;strong&gt;deg⁻(v) = 4&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyrcw67ecqyfbtnq2fr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foyrcw67ecqyfbtnq2fr7.png" alt="Illustration of criteria 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two ways into the vertex and four out of it, so even if you were to start from this vertex, you can at most cover three of the four outgoing vertices.&lt;/p&gt;

&lt;h4&gt;
  
  
  Criteria 3
&lt;/h4&gt;

&lt;p&gt;For all the vertices excluding the starting and the ending vertex, the &lt;strong&gt;deg⁺(v)&lt;/strong&gt; must be equal to &lt;strong&gt;deg⁻(v)&lt;/strong&gt;; this ensures that for every way into the vertex, there's a way out. If this is true for the starting and ending vertices as well, then we have an Euler circuit. Otherwise, we can have &lt;strong&gt;deg⁻(v) - deg⁺(v) = 1&lt;/strong&gt; for the starting vertex, which ensures that for every edge entering the vertex, there is a corresponding way out, with one additional outgoing edge reserved for the initial move. Similarly, for the ending vertex, we can have &lt;strong&gt;deg⁺(v) - deg⁻(v) = 1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2bw58dp0u70cw95f8dca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2bw58dp0u70cw95f8dca.png" alt="Illustration of Euler path"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider the sequence of vertices s, a, b, c, a, d, t.&lt;/p&gt;

&lt;p&gt;For an undirected graph, this can be succinctly expressed as:&lt;br&gt;
"There's an Euler path if the degree of exactly two of the vertices is odd, and an Euler circuit if the degree of none of the vertices is odd".&lt;/p&gt;

&lt;h2&gt;
  
  
  Hierholzer's Algorithm
&lt;/h2&gt;

&lt;p&gt;The basic idea of Hierholzer's algorithm is the stepwise construction of the Eulerian path by connecting disjoint cycles.&lt;/p&gt;

&lt;p&gt;First, we ensure that an Euler path or circuit exists by the above-stated criteria. If either one fails, then we can't have an Euler path or circuit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algorithm
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Begin at a starting vertex (the designated start if one exists, otherwise any vertex with edges). Follow edges successively, choosing each edge only once, until you can no longer continue. This produces an initial trail that either forms a closed cycle (Euler circuit case) or ends at the terminal vertex (Euler path case).&lt;/li&gt;
&lt;li&gt;If there remain unused edges, find a vertex on the current trail that still has unvisited outgoing edges. From this vertex, construct another trail in the same way, and then splice it into the original trail. Repeating this process until all edges are used yields the Euler path or circuit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2b1xpdh32mq83doboif.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2b1xpdh32mq83doboif.png" alt="Illustration of Hierholzer algo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Link to Hierholzer's algorithm's implementation in different languages: &lt;a href="https://rosettacode.org/wiki/Hierholzer%27s_algorithm" rel="noopener noreferrer"&gt;Implementation of the algorithm&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Euler paths and circuits arise in many applications throughout computer science and other disciplines, where they can be used to find optimal routes minimizing travel distance and ensuring complete coverage of an area, amongst others, and it is of utmost importance to find an efficient solution to this problem, something that this algorithm offers to do in &lt;strong&gt;O(E)&lt;/strong&gt; time complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg" rel="noopener noreferrer"&gt;Königsberg Bridges Problem - Wikipedia&lt;/a&gt;: Overview of the historical problem that inspired Euler's work on graph theory.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Handshaking_lemma" rel="noopener noreferrer"&gt;Graph Theory - Handshaking Lemma - Wikipedia&lt;/a&gt;: Explanation of the Handshake Theorem, including the sum of degrees and its applications.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rosettacode.org/wiki/Hierholzer%27s_algorithm" rel="noopener noreferrer"&gt;Hierholzer's Algorithm - Rosetta Code&lt;/a&gt;: Implementation examples of Hierholzer’s algorithm for finding Eulerian paths and circuits in different programming languages.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Understanding Tarjan’s Algorithm with Visual Examples</title>
      <dc:creator>Muhammad Taaha Tariq</dc:creator>
      <pubDate>Fri, 29 Aug 2025 12:03:52 +0000</pubDate>
      <link>https://dev.to/muhammad_taaha_90438c47f1/understanding-tarjans-algorithm-with-visual-examples-5hb8</link>
      <guid>https://dev.to/muhammad_taaha_90438c47f1/understanding-tarjans-algorithm-with-visual-examples-5hb8</guid>
      <description>&lt;h2&gt;
  
  
  Tarjan's algorithm
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Muhammad Taaha Tariq&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;August 2025&lt;/em&gt;  &lt;/p&gt;


&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Graphs are widely used to model real-world systems such as social networks, communication channels, and dependency structures. In directed graphs, cycles are particularly significant, and analyzing them through Strongly Connected Components (SCCs) provides valuable insight into the graph’s structure.&lt;/p&gt;

&lt;p&gt;An SCC is defined as a subset of nodes in which every node is reachable from every other node within the same subset. Identifying these components is important in applications like deadlock detection, dependency analysis, and compiler optimization.&lt;/p&gt;

&lt;p&gt;Among the most efficient methods for this task is Tarjan’s Algorithm, which leverages Depth-First Search (DFS) along with discovery and low-link values to compute SCCs in linear time. This article explains the concept of SCCs and illustrates Tarjan’s Algorithm step by step with examples.  &lt;/p&gt;

&lt;p&gt;But before diving right into the algorithm, here's a brief recap of the associated concepts.  &lt;/p&gt;


&lt;h2&gt;
  
  
  Graph
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)" rel="noopener noreferrer"&gt;graph&lt;/a&gt; is a mathematical structure, particularly in graph theory, consisting of vertices(nodes) and edges that interlink the nodes with each other. In the context of computer science, however, a graph refers to a data structure whose vertices represent some kind of entity(it may be a network node or some data) that is linked to other vertices using connection links(edges).&lt;/p&gt;

&lt;p&gt;It consists of two sets:  &lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;V=v  ∣  set of all vertices\mathbf{V} = { v \;|\; \text{set of all vertices} } &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbf"&gt;V&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;set of all vertices&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;
 
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;E=e  ∣  set of all the edges\mathbf{E} = { e \; |\; \text{set of all the edges}} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbf"&gt;E&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;set of all the edges&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
  

&lt;p&gt;Pictorially, it is depicted as circles connected by lines or arrows for different types of graphs.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpw4sbv4fyrdbhetbv4iu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpw4sbv4fyrdbhetbv4iu.png" alt="Undirected Graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two nodes are said to be &lt;strong&gt;adjacent&lt;/strong&gt; if they have an interconnecting edge between them. &lt;em&gt;Adjacency&lt;/em&gt; simplifies the concept of interconnection by considering only the nodes adjacent to a given node. Given the above graph, we see that the adjacency list of node A is:&lt;br&gt;&lt;br&gt;
 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;[B,  C][\text{B}, \; \text{C}] &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;B&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;C&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;Furthermore, edges can be directed or undirected. A &lt;em&gt;directed edge&lt;/em&gt; represents a unidirectional connection between the two nodes wherein we can only move from one node to the other but not in the other direction, and is commonly depicted with a pointed arrow.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tst4tse88c4ewtky57e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7tst4tse88c4ewtky57e.png" alt="directed edge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An &lt;em&gt;undirected edge&lt;/em&gt;, on the other hand, represents a bidirectional connection between the two nodes.  &lt;/p&gt;

&lt;p&gt;Based on the nature of the edges between the nodes of a graph, there are two types of graphs that are commonly used in computer science: &lt;strong&gt;undirected graphs&lt;/strong&gt; and &lt;strong&gt;directed graphs&lt;/strong&gt;.  &lt;/p&gt;




&lt;h3&gt;
  
  
  Strongly Connected Components
&lt;/h3&gt;

&lt;p&gt;A strongly connected component of a directed graph is a &lt;em&gt;maximal subgraph&lt;/em&gt; where each vertex(node) is mutually reachable.  &lt;/p&gt;

&lt;p&gt;A &lt;em&gt;subgraph&lt;/em&gt; refers to a portion of a graph, or more formally, a subset of the vertex set. The &lt;em&gt;maximality condition&lt;/em&gt; refers to the fact that the subgraph cannot be extended while maintaining mutual reachability.  &lt;/p&gt;

&lt;p&gt;The strongly connected components, therefore, partition the graph into disjoint subgraphs.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fecdf7cxq1a8sw55zn4n6.png" alt="SCCs"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Depth-first Search
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Depth-first Search&lt;/em&gt; is a traversal algorithm that traverses the graph recursively. The important thing to note is that it traverses the graph as a spanning tree.  &lt;/p&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/Spanning_tree" rel="noopener noreferrer"&gt;spanning tree&lt;/a&gt; of a &lt;a href="https://en.wikipedia.org/wiki/Connectivity_(graph_theory)" rel="noopener noreferrer"&gt;connected graph&lt;/a&gt; connects all the nodes of the graph using the minimum number of edges and contains no &lt;a href="https://en.wikipedia.org/wiki/Cycle_(graph_theory)" rel="noopener noreferrer"&gt;cycles&lt;/a&gt;. Since there are many spanning trees of a graph, the &lt;strong&gt;DFS&lt;/strong&gt; traversal order is not unique.  &lt;/p&gt;

&lt;p&gt;Considering the graph in &lt;em&gt;figure 1&lt;/em&gt; and starting at A, one possible spanning tree is:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14i4qhd0993tm4ir6spu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14i4qhd0993tm4ir6spu.png" alt="Spanning tree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DFS traversal that produces this spanning tree is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start at A.&lt;/li&gt;
&lt;li&gt;Recursively, call the routine for B. Then, for D and finally for C.&lt;/li&gt;
&lt;li&gt;Then, we backtrack to A.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, during the traversal, we need to keep track of already visited nodes to prevent indefinite behavior because of cycles, which can be achieved by using an array.  &lt;/p&gt;




&lt;h3&gt;
  
  
  Some additional concepts
&lt;/h3&gt;

&lt;p&gt;DFS spanning trees have two kinds of edges: &lt;strong&gt;tree edges&lt;/strong&gt; and &lt;strong&gt;back edges&lt;/strong&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Back edges&lt;/em&gt; relate a tree node to its ancestor in the traversal order.
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Tree edges&lt;/em&gt; take us from the parent node to its children.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the two most important concepts responsible for this algorithm's efficiency are &lt;em&gt;discovery time&lt;/em&gt; and &lt;em&gt;low values&lt;/em&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery time&lt;/strong&gt; is the time it takes for the DFS to reach a node.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low values&lt;/strong&gt; indicate the smallest discovery time reachable from a node. Low values less than a node's discovery time indicate a back edge (a cycle).
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tarjan's algorithm for directed graphs
&lt;/h2&gt;

&lt;p&gt;Tarjan's algorithm is used to find the Strongly Connected Components(SCCs) of a directed graph.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algorithm&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start at any vertex and assign it a discovery time and a low value of 0.
&lt;/li&gt;
&lt;li&gt;Iterate over its adjacent nodes, and we push them onto a stack to keep track of the order in which they were traversed, which is essential to correctly updating the low values and identifying potential SSCs, and for the unvisited nodes, recursively call DFS.
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For each subsequent node:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the adjacent node has already been visited (back edge), update:

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;low[u]=min⁡(low[u],  disc[v])low[u] = \min(low[u], \; disc[v])  &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;min&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;sc&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;If the adjacent node has not been visited yet, call DFS and on backtracking, update:

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;low[u]=min⁡(low[u],  low[v])low[u] = \min(low[u], \; low[v])  &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;min&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SCC identification:&lt;/strong&gt; If  &lt;/p&gt;

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;low[u]=disc[u]low[u] = disc[u] &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;sc&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;, then u is the root of an SCC. Pop nodes from the stack until u is popped.  &lt;/p&gt;
&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu4xqb5m82fufjmspn8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu4xqb5m82fufjmspn8u.png" alt="Explanation"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Tarjan's algorithm for undirected graphs
&lt;/h2&gt;

&lt;p&gt;A slightly modified version of Tarjan's algorithm is used for undirected graphs to find the bridges and articulation points.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algorithm&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start at any vertex and assign it a discovery time and a low value of 0.
&lt;/li&gt;
&lt;li&gt;Iterate over adjacent nodes, calling DFS with the parent node.
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For each node:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the adjacent node is the parent, skip.
&lt;/li&gt;
&lt;li&gt;If already visited, update:

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;low[u]=min⁡(low[u],  disc[v])low[u] = \min(low[u], \; disc[v]) &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;min&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;sc&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
 &lt;/li&gt;
&lt;li&gt;Otherwise, DFS recursively and backtrack update:

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;low[u]=min⁡(low[u],  low[v])low[u] = \min(low[u], \; low[v]) &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;min&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Bridge check:&lt;/strong&gt; If  &lt;/p&gt;

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;low[u]&amp;gt;disc[v]low[u] &amp;gt; disc[v] &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;sc&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;, then (u, v) is a bridge.  &lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Articulation point check:&lt;/strong&gt; If  &lt;/p&gt;

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;disc[u]&amp;lt;=low[v]disc[u] &amp;lt;= low[v] &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;sc&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;w&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;, then u is an articulation point (except the root).  &lt;/p&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; In undirected graphs, we skip the parent node because otherwise every parent-child edge looks like a bridge.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The importance of graphs for computer networks and, in general, for computers cannot be overemphasized, and as such, graphs arise in many different applications, and with them arises the need to efficiently work with them on a large scale something that is supplemented by the development of new and more efficient algorithms, one example of such an algorithm is the Tarjan's algorithm which partitions the graph in linear time complexity &lt;em&gt;O(V + E).&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;R. E. Tarjan. &lt;em&gt;Depth-first search and linear graph algorithms&lt;/em&gt;. SIAM Journal on Computing, 1(2), 146–160, 1972. doi:10.1137/0201010.
&lt;/li&gt;
&lt;li&gt;T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. &lt;em&gt;Introduction to Algorithms&lt;/em&gt;, 3rd Edition. MIT Press, 2009.
&lt;/li&gt;
&lt;li&gt;GeeksforGeeks. &lt;a href="https://www.geeksforgeeks.org/tarjan-algorithm-find-strongly-connected-components/" rel="noopener noreferrer"&gt;Tarjan’s Algorithm to Find Strongly Connected Components&lt;/a&gt;. Accessed: Aug 2025.
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>datastructures</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
