{"id":22,"date":"2026-06-28T07:00:13","date_gmt":"2026-06-28T07:00:13","guid":{"rendered":"https:\/\/algovelgo.com\/?p=22"},"modified":"2026-06-28T07:29:31","modified_gmt":"2026-06-28T07:29:31","slug":"dijkstras-algorithm-all-you-need-to-know","status":"publish","type":"post","link":"https:\/\/algovelgo.com\/?p=22","title":{"rendered":"Dijkstra&#8217;s Algorithm : All you need to know"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Dijkstra&#8217;s Algorithm: A Comprehensive Guide<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before directly jumping to Dijkstra&#8217;s Algorithm, let&#8217;s first understand some basic concepts related to it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Weighted Graph<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A weighted graph is a network of vertices (nodes) connected by edges, where each edge has a weight. The <strong>weight<\/strong> is a numerical value representing cost, distance, time, capacity, or any other metric associated with traversing that edge. The weights tell you the cost of using that edge.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world Examples:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Social Networks:<\/strong> People are nodes, friendship connections are edges, and relationship strength is the weight.<\/li>\n\n\n\n<li><strong>Flight Routes:<\/strong> Airports are nodes, flights are edges, and ticket price or flight duration is the weight.<\/li>\n\n\n\n<li><strong>Road Networks:<\/strong> Cities are nodes, roads are edges, and distance or travel time is the weight.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Key Graph Terms:<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Term<\/th><th class=\"has-text-align-left\" data-align=\"left\">Definition<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>Path<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">A sequence of edges connecting two vertices.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><strong>Shortest Path<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">The path between two vertices that has the minimum sum of edge weights.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What is Dijkstra&#8217;s Algorithm?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dijkstra&#8217;s Algorithm is the classic greedy algorithm designed to solve the <strong>single-source shortest path<\/strong> problem on a weighted graph.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Problem Statement:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Given:<\/strong> A weighted graph with non-negative edge weights and a starting source vertex (s).<\/li>\n\n\n\n<li><strong>Find:<\/strong> The shortest path from (s) to every other reachable vertex in the graph.<\/li>\n\n\n\n<li><strong>Output:<\/strong><\/li>\n\n\n\n<li><code>dist[]<\/code>: An array where <code>dist[v]<\/code> is the shortest distance from source (s) to vertex (v).<\/li>\n\n\n\n<li><code>parent[]<\/code>: An array where <code>parent[v]<\/code> holds the predecessor of (v) on the shortest path (used for path reconstruction).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world Analogy (GPS Navigation):<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine you are at home, and Google Maps needs to find the fastest route to a restaurant. Google&#8217;s servers run Dijkstra&#8217;s algorithm on a road network graph where each road&#8217;s weight is the travel time. In a single run, Dijkstra computes the fastest path not just to your chosen restaurant, but to <strong>every<\/strong> reachable location from your house. This is why Google Maps can instantly show you alternative routes and arrival times to nearby places\u201a\u00c4\u00eethey are all computed at once!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Intuition (The Water Flood Analogy):<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine water flooding a network of pipes from your starting location. The water spreads in all directions simultaneously but travels faster through shorter, lower-resistance paths. The first moment water reaches a city is guaranteed to be the fastest path. Dijkstra&#8217;s algorithm simulates this process step-by-step.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Step-by-Step Algorithm<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Initialization:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Set <code>dist[source] = 0<\/code> and <code>dist[v] = \u221e;<\/code> for all other vertices (v).<\/li>\n\n\n\n<li>Set <code>parent[v] = null<\/code> for all vertices.<\/li>\n\n\n\n<li>Create an empty priority queue (min-heap) <code>pq<\/code> and push <code>(0, source)<\/code> into it.<\/li>\n\n\n\n<li>Keep track of visited nodes using an empty set or array.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">2. Main Loop:<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">While the priority queue <code>pq<\/code> is not empty:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Extract the pair <code>(distance, u)<\/code> with the minimum distance.<\/li>\n\n\n\n<li>If <code>u<\/code> is already visited, skip it.<\/li>\n\n\n\n<li>Mark <code>u<\/code> as visited.<\/li>\n\n\n\n<li>For each neighbor <code>v<\/code> of <code>u<\/code>:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Calculate <code>new_distance = dist[u] + weight(u, v)<\/code>.<\/li>\n\n\n\n<li><strong>Relaxation Step:<\/strong> If <code>new_distance &lt; dist[v]<\/code>:\n<ul class=\"wp-block-list\">\n<li>Update <code>dist[v] = new_distance<\/code>.<\/li>\n\n\n\n<li>Update <code>parent[v] = u<\/code>.<\/li>\n\n\n\n<li>Push <code>(new_distance, v)<\/code> into the priority queue.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Pseudocode<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>Algorithm: Dijkstra(graph, source)\nInput: A graph with vertices and weighted edges, and a starting vertex source\nOutput: dist&#91;] (shortest distances) and parent&#91;] (predecessor path trackers)\n\nfor each vertex v in graph:\n    dist&#91;v] = INFINITY\n    parent&#91;v] = NULL\n\ndist&#91;source] = 0\npriority_queue pq = empty min-heap\npq.push((0, source))\nvisited = empty set\n\nwhile pq is not empty:\n    current_dist, u = pq.pop()  # Extract the vertex with the minimum distance\n\n    if u in visited:\n        continue  # Skip already processed vertices\n\n    visited.add(u)\n\n    for each vertex v adjacent to u:\n        weight = edge_weight(u, v)\n\n        # Relaxation Step\n        if dist&#91;u] + weight &lt; dist&#91;v]:\n            dist&#91;v] = dist&#91;u] + weight\n            parent&#91;v] = u\n            pq.push((dist&#91;v], v))\n\nreturn dist, parent<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Walkthrough Example<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Graph Definition:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Vertices:<\/strong> A, B, C, D, E<\/li>\n\n\n\n<li><strong>Edges:<\/strong> A-B (4), A-C (2), B-C (1), B-D (5), B-E (6), C-D (8), C-E (10), D-E (2)<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Step 1: Initialization<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>dist:    &#91;A:0, B:\u221e, C:\u221e, D:\u221e, E:\u221e]\nparent:  &#91;A:null, B:null, C:null, D:null, E:null]\nvisited: &#91;]\npq:      &#91;(0, A)]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2: Process A<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extract <code>(0, A)<\/code> from <code>pq<\/code> and mark <code>A<\/code> as visited.<\/li>\n\n\n\n<li>Explore <code>A<\/code>&#8216;s neighbors:<\/li>\n\n\n\n<li><strong>B:<\/strong> <code>0 + 4 = 4 <code>&lt;<\/code> \u221e<\/code>. Update <code>dist[B] = 4<\/code>, <code>parent[B] = A<\/code>.<\/li>\n\n\n\n<li><strong>C:<\/strong> <code>0 + 2 = 2 &lt; \u221e<\/code>. Update <code>dist[C] = 2<\/code>, <code>parent[C] = A<\/code>.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>dist:    &#91;A:0, B:4, C:2, D:&amp;infin;, E:&amp;infin;]\nvisited: &#91;A]\npq:      &#91;(2, C), (4, B)]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 3: Process C<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extract <code>(2, C)<\/code> from <code>pq<\/code> and mark <code>C<\/code> as visited.<\/li>\n\n\n\n<li>Explore <code>C<\/code>&#8216;s neighbors:<\/li>\n\n\n\n<li><strong>A:<\/strong> Already visited, skip.<\/li>\n\n\n\n<li><strong>B:<\/strong> <code>2 + 1 = 3 &lt; 4<\/code>. Update <code>dist[B] = 3<\/code>, <code>parent[B] = C<\/code>.<\/li>\n\n\n\n<li><strong>D:<\/strong> <code>2 + 8 = 10 &lt; \u221e<\/code>. Update <code>dist[D] = 10<\/code>, <code>parent[D] = C<\/code>.<\/li>\n\n\n\n<li><strong>E:<\/strong> <code>2 + 10 = 12 &lt; \u221e<\/code>. Update <code>dist[E] = 12<\/code>, <code>parent[E] = C<\/code>.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>dist:    &#91;A:0, B:3, C:2, D:10, E:12]\nvisited: &#91;A, C]\npq:      &#91;(3, B), (4, B), (10, D), (12, E)]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 4: Process B<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extract <code>(3, B)<\/code> from <code>pq<\/code> and mark <code>B<\/code> as visited.<\/li>\n\n\n\n<li>Explore <code>B<\/code>&#8216;s neighbors:<\/li>\n\n\n\n<li><strong>A, C:<\/strong> Already visited, skip.<\/li>\n\n\n\n<li><strong>D:<\/strong> <code>3 + 5 = 8 &lt; 10<\/code>. Update <code>dist[D] = 8<\/code>, <code>parent[D] = B<\/code>.<\/li>\n\n\n\n<li><strong>E:<\/strong> <code>3 + 6 = 9 &lt; 12<\/code>. Update <code>dist[E] = 9<\/code>, <code>parent[E] = B<\/code>.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>dist:    &#91;A:0, B:3, C:2, D:8, E:9]\nvisited: &#91;A, C, B]\npq:      &#91;(4, B), (8, D), (9, E), (10, D), (12, E)]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 5: Process D<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extract <code>(4, B)<\/code> from <code>pq<\/code>. Since <code>B<\/code> is already visited, skip.<\/li>\n\n\n\n<li>Extract <code>(8, D)<\/code> from <code>pq<\/code> and mark <code>D<\/code> as visited.<\/li>\n\n\n\n<li>Explore <code>D<\/code>&#8216;s neighbors:<\/li>\n\n\n\n<li><strong>B, C:<\/strong> Already visited, skip.<\/li>\n\n\n\n<li><strong>E:<\/strong> <code>8 + 2 = 10 > 9<\/code>. No update needed (9 is already shorter).<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>dist:    &#91;A:0, B:3, C:2, D:8, E:9]\nvisited: &#91;A, C, B, D]\npq:      &#91;(9, E), (10, D), (12, E)]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 6: Process E<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extract <code>(9, E)<\/code> from <code>pq<\/code> and mark <code>E<\/code> as visited.<\/li>\n\n\n\n<li><code>E<\/code> has no unvisited neighbors.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>dist:    &#91;A:0, B:3, C:2, D:8, E:9]\nvisited: &#91;A, C, B, D, E]\npq:      empty<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Final Results (Shortest Path from A):<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>A \u2192 A:<\/strong> Cost: <code>0<\/code><\/li>\n\n\n\n<li><strong>A \u2192 B:<\/strong> Cost: <code>3<\/code> (Path: <code>A \u2192 C \u2192 B<\/code>)<\/li>\n\n\n\n<li><strong>A \u2192 C:<\/strong> Cost: <code>2<\/code> (Path: <code>A \u2192 C<\/code>)<\/li>\n\n\n\n<li><strong>A \u2192 D:<\/strong> Cost: <code>8<\/code> (Path: <code>A \u2192 C \u2192 B \u2192 D<\/code>)<\/li>\n\n\n\n<li><strong>A \u2192 E:<\/strong> Cost: <code>9<\/code> (Path: <code>A \u2192 C \u2192 B \u2192 E<\/code>)<\/li>\n\n\n\n<li><strong>Path Reconstruction to E:<\/strong> <code>E \u2190 B \u2190 C \u2190 A<\/code> (Reverse order of parents).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Complexity Analysis<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Time Complexity:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>With Binary Min-Heap:<\/strong> <strong>(O((V + E) log V))<\/strong><\/li>\n\n\n\n<li>(V) insertions\/extractions from the heap: (O(V log V))<\/li>\n\n\n\n<li>(E) relaxation operations (decrease-key): (O(E log V))<\/li>\n\n\n\n<li><strong>With Array (Linear Search):<\/strong> <strong>(O(V^2))<\/strong><\/li>\n\n\n\n<li>Preferred for extremely dense graphs where (E \\approx V^2).<\/li>\n\n\n\n<li><strong>With Fibonacci Heap:<\/strong> <strong>(O(E + V log V))<\/strong><\/li>\n\n\n\n<li>High constant factor; primarily of theoretical interest and rarely used in production.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Space Complexity:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>(O(V + E))<\/strong> to store the graph adjacency list representation.<\/li>\n\n\n\n<li><strong>(O(V))<\/strong> helper storage for <code>dist[]<\/code>, <code>parent[]<\/code> tracking, and the priority queue states.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Interactive Dijkstra&#8217;s Algorithm Visualizer<\/title>\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Outfit:wght@300;400;600;800&#038;family=Plus+Jakarta+Sans:wght@300;400;500;600;700&#038;display=swap\" rel=\"stylesheet\">\n  <style>\n    :root {\n      --bg-dark: #0f172a;\n      --bg-card: rgba(30, 41, 59, 0.7);\n      --border-color: rgba(255, 255, 255, 0.08);\n      --text-main: #f8fafc;\n      --text-muted: #94a3b8;\n      \n      \/* Theme colors *\/\n      --color-primary: #3b82f6; \/* Blue for general *\/\n      --color-success: #10b981; \/* Green for visited *\/\n      --color-warning: #f59e0b; \/* Amber for currently processing *\/\n      --color-danger: #ef4444;\n      --color-accent: #a855f7;  \/* Purple for queue\/updating *\/\n      \n      \/* Neon glow effects *\/\n      --glow-visited: 0 0 15px rgba(16, 185, 129, 0.6);\n      --glow-processing: 0 0 15px rgba(245, 158, 11, 0.8);\n      --glow-updating: 0 0 15px rgba(168, 85, 247, 0.6);\n    }\n\n    * {\n      box-sizing: border-box;\n      margin: 0;\n      padding: 0;\n    }\n\n    body {\n      font-family: 'Plus Jakarta Sans', sans-serif;\n      background-color: var(--bg-dark);\n      background-image: \n        radial-gradient(at 0% 0%, rgba(59, 130, 246, 0.1) 0px, transparent 50%),\n        radial-gradient(at 100% 100%, rgba(168, 85, 247, 0.1) 0px, transparent 50%);\n      color: var(--text-main);\n      min-height: 100vh;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      padding: 2rem 1rem;\n      overflow-x: hidden;\n    }\n\n    .container {\n      width: 100%;\n      max-width: 1200px;\n      margin: 0 auto;\n    }\n\n    header {\n      text-align: center;\n      margin-bottom: 2rem;\n    }\n\n    h1 {\n      font-family: 'Outfit', sans-serif;\n      font-size: 2.5rem;\n      font-weight: 800;\n      background: linear-gradient(135deg, #60a5fa 0%, #c084fc 100%);\n      -webkit-background-clip: text;\n      -webkit-text-fill-color: transparent;\n      margin-bottom: 0.5rem;\n      letter-spacing: -0.02em;\n    }\n\n    header p {\n      color: var(--text-muted);\n      font-size: 1.1rem;\n    }\n\n    \/* Grid Layout *\/\n    .visualizer-grid {\n      display: grid;\n      grid-template-columns: 1.2fr 0.8fr;\n      gap: 1.5rem;\n      margin-bottom: 1.5rem;\n    }\n\n    @media (max-width: 968px) {\n      .visualizer-grid {\n        grid-template-columns: 1fr;\n      }\n    }\n\n    .card {\n      background: var(--bg-card);\n      backdrop-filter: blur(12px);\n      -webkit-backdrop-filter: blur(12px);\n      border: 1px solid var(--border-color);\n      border-radius: 16px;\n      padding: 1.5rem;\n      box-shadow: 0 10px 30px -10px rgba(0,0,0,0.5);\n      display: flex;\n      flex-direction: column;\n      position: relative;\n      overflow: hidden;\n    }\n\n    .card-title {\n      font-family: 'Outfit', sans-serif;\n      font-size: 1.25rem;\n      font-weight: 600;\n      margin-bottom: 1rem;\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      color: var(--text-main);\n      border-bottom: 1px solid var(--border-color);\n      padding-bottom: 0.5rem;\n    }\n\n    \/* Graph Section *\/\n    .graph-container {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      background: rgba(15, 23, 42, 0.5);\n      border-radius: 12px;\n      border: 1px solid rgba(255, 255, 255, 0.04);\n      padding: 1rem;\n      position: relative;\n      height: 380px;\n    }\n\n    #graph-svg {\n      width: 100%;\n      height: 100%;\n    }\n\n    svg {\n      user-select: none;\n    }\n\n    \/* SVG Elements styling *\/\n    .edge {\n      stroke: #475569;\n      stroke-width: 3;\n      stroke-linecap: round;\n      transition: stroke 0.3s, stroke-width 0.3s, stroke-dasharray 0.3s;\n    }\n\n    .edge.active {\n      stroke: var(--color-success);\n      stroke-width: 4;\n    }\n\n    .edge.updating {\n      stroke: var(--color-accent);\n      stroke-width: 4;\n      stroke-dasharray: 8 4;\n      animation: dash 1s linear infinite;\n    }\n    \n    .edge.shortest-path {\n      stroke: #38bdf8;\n      stroke-width: 5;\n    }\n\n    @keyframes dash {\n      to {\n        stroke-dashoffset: -12;\n      }\n    }\n\n    .edge-label-bg {\n      fill: var(--bg-dark);\n      rx: 4;\n      ry: 4;\n    }\n\n    .edge-label {\n      fill: var(--text-muted);\n      font-size: 14px;\n      font-weight: 600;\n      text-anchor: middle;\n      dominant-baseline: central;\n    }\n\n    .edge-label.active {\n      fill: var(--text-main);\n    }\n\n    .node-circle {\n      fill: #1e293b;\n      stroke: #64748b;\n      stroke-width: 3;\n      transition: fill 0.3s, stroke 0.3s, filter 0.3s;\n      cursor: pointer;\n    }\n\n    .node-circle:hover {\n      fill: #334155;\n    }\n\n    .node.visited .node-circle {\n      fill: rgba(16, 185, 129, 0.15);\n      stroke: var(--color-success);\n      filter: drop-shadow(var(--glow-visited));\n    }\n\n    .node.processing .node-circle {\n      fill: rgba(245, 158, 11, 0.2);\n      stroke: var(--color-warning);\n      filter: drop-shadow(var(--glow-processing));\n      animation: pulse 2s infinite;\n    }\n\n    .node.target .node-circle {\n      fill: rgba(168, 85, 247, 0.2);\n      stroke: var(--color-accent);\n      filter: drop-shadow(var(--glow-updating));\n    }\n\n    @keyframes pulse {\n      0% {\n        stroke-width: 3px;\n      }\n      50% {\n        stroke-width: 5px;\n      }\n      100% {\n        stroke-width: 3px;\n      }\n    }\n\n    .node-text {\n      fill: var(--text-main);\n      font-size: 16px;\n      font-weight: 700;\n      text-anchor: middle;\n      dominant-baseline: central;\n      pointer-events: none;\n    }\n\n    \/* Control Panel *\/\n    .controls-card {\n      width: 100%;\n      margin-bottom: 1.5rem;\n    }\n\n    .controls-wrapper {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 1rem;\n      align-items: center;\n      justify-content: space-between;\n    }\n\n    .btn-group {\n      display: flex;\n      gap: 0.5rem;\n    }\n\n    button {\n      background: rgba(255, 255, 255, 0.05);\n      border: 1px solid var(--border-color);\n      color: var(--text-main);\n      padding: 0.6rem 1.2rem;\n      border-radius: 8px;\n      cursor: pointer;\n      font-weight: 600;\n      font-size: 0.9rem;\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      transition: background 0.2s, border-color 0.2s, transform 0.1s;\n    }\n\n    button:hover:not(:disabled) {\n      background: rgba(255, 255, 255, 0.1);\n      border-color: rgba(255, 255, 255, 0.2);\n    }\n\n    button:active:not(:disabled) {\n      transform: scale(0.97);\n    }\n\n    button:disabled {\n      opacity: 0.4;\n      cursor: not-allowed;\n    }\n\n    button.primary {\n      background: var(--color-primary);\n      border-color: transparent;\n    }\n\n    button.primary:hover:not(:disabled) {\n      background: #2563eb;\n    }\n\n    .slider-container {\n      display: flex;\n      align-items: center;\n      gap: 1rem;\n      flex-grow: 1;\n      max-width: 400px;\n    }\n\n    .slider-label {\n      font-size: 0.9rem;\n      color: var(--text-muted);\n      white-space: nowrap;\n      min-width: 80px;\n    }\n\n    input[type=\"range\"] {\n      -webkit-appearance: none;\n      width: 100%;\n      height: 6px;\n      border-radius: 3px;\n      background: #334155;\n      outline: none;\n      cursor: pointer;\n    }\n\n    input[type=\"range\"]::-webkit-slider-thumb {\n      -webkit-appearance: none;\n      width: 18px;\n      height: 18px;\n      border-radius: 50%;\n      background: var(--color-primary);\n      box-shadow: 0 0 10px rgba(59, 130, 246, 0.5);\n      transition: transform 0.1s;\n    }\n\n    input[type=\"range\"]::-webkit-slider-thumb:hover {\n      transform: scale(1.2);\n    }\n\n    \/* State & Info Panel Styling *\/\n    .step-desc {\n      font-size: 0.95rem;\n      line-height: 1.5;\n      color: var(--text-main);\n      background: rgba(15, 23, 42, 0.4);\n      border-left: 4px solid var(--color-primary);\n      padding: 0.75rem 1rem;\n      border-radius: 0 8px 8px 0;\n      margin-bottom: 1.25rem;\n      min-height: 80px;\n    }\n\n    .step-desc.visited-update {\n      border-left-color: var(--color-success);\n    }\n\n    .state-section {\n      margin-bottom: 1.25rem;\n    }\n\n    .state-section-title {\n      font-size: 0.85rem;\n      text-transform: uppercase;\n      letter-spacing: 0.05em;\n      color: var(--text-muted);\n      margin-bottom: 0.5rem;\n      font-weight: 700;\n    }\n\n    \/* Badges list *\/\n    .badge-list {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 0.5rem;\n    }\n\n    .badge {\n      display: inline-flex;\n      align-items: center;\n      padding: 0.25rem 0.6rem;\n      border-radius: 6px;\n      font-size: 0.85rem;\n      font-weight: 600;\n      background: rgba(255, 255, 255, 0.05);\n      border: 1px solid var(--border-color);\n    }\n\n    .badge.visited {\n      background: rgba(16, 185, 129, 0.1);\n      border-color: rgba(16, 185, 129, 0.2);\n      color: #34d399;\n    }\n\n    .badge.processing {\n      background: rgba(245, 158, 11, 0.1);\n      border-color: rgba(245, 158, 11, 0.2);\n      color: #fbbf24;\n    }\n    \n    .badge.queue-item {\n      background: rgba(168, 85, 247, 0.1);\n      border-color: rgba(168, 85, 247, 0.2);\n      color: #c084fc;\n    }\n\n    \/* Tables *\/\n    table {\n      width: 100%;\n      border-collapse: collapse;\n      font-size: 0.9rem;\n      text-align: left;\n    }\n\n    th, td {\n      padding: 0.5rem 0.75rem;\n      border-bottom: 1px solid rgba(255, 255, 255, 0.05);\n    }\n\n    th {\n      color: var(--text-muted);\n      font-weight: 600;\n      font-size: 0.8rem;\n      text-transform: uppercase;\n    }\n\n    tr:last-child td {\n      border-bottom: none;\n    }\n\n    .val-cell {\n      font-weight: 700;\n    }\n\n    .updated-val {\n      animation: highlight-green 1.5s ease-out;\n    }\n\n    @keyframes highlight-green {\n      0% {\n        color: var(--color-success);\n        background: rgba(16, 185, 129, 0.25);\n        border-radius: 4px;\n      }\n      100% {\n        color: inherit;\n        background: transparent;\n      }\n    }\n    \n    .final-path-box {\n      background: rgba(56, 189, 248, 0.1);\n      border: 1px solid rgba(56, 189, 248, 0.2);\n      padding: 0.75rem;\n      border-radius: 8px;\n      font-family: monospace;\n      font-size: 1rem;\n      color: #38bdf8;\n      display: flex;\n      flex-direction: column;\n      gap: 0.5rem;\n    }\n\n    \/* Embedded iframe optimization *\/\n    .embed-info {\n      text-align: center;\n      margin-top: 1.5rem;\n      font-size: 0.85rem;\n      color: var(--text-muted);\n    }\n\n    .embed-code {\n      background: #090d16;\n      border: 1px solid rgba(255, 255, 255, 0.05);\n      border-radius: 6px;\n      padding: 0.5rem;\n      font-family: monospace;\n      font-size: 0.8rem;\n      margin-top: 0.5rem;\n      display: inline-block;\n      max-width: 100%;\n      overflow-x: auto;\n      color: #e2e8f0;\n    }\n\n    \/* Arrow in list *\/\n    .arrow-icon {\n      margin: 0 0.25rem;\n      color: var(--text-muted);\n    }\n\n    \/* Info grid at bottom *\/\n    .info-grid {\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 1.5rem;\n      margin-top: 1.5rem;\n      margin-bottom: 2rem;\n    }\n\n    @media (max-width: 768px) {\n      .info-grid {\n        grid-template-columns: 1fr;\n      }\n    }\n\n    .info-list {\n      list-style: none;\n      display: flex;\n      flex-direction: column;\n      gap: 0.75rem;\n    }\n\n    .info-list li {\n      display: flex;\n      align-items: flex-start;\n      gap: 0.5rem;\n      font-size: 0.95rem;\n      line-height: 1.5;\n    }\n\n    .info-list li span.icon {\n      flex-shrink: 0;\n      margin-top: 0.1rem;\n    }\n\n    .info-card-success {\n      border-top: 4px solid var(--color-success) !important;\n    }\n\n    .info-card-warning {\n      border-top: 4px solid var(--color-danger) !important;\n    }\n\n    .alert-box {\n      background: rgba(239, 68, 68, 0.08);\n      border: 1px solid rgba(239, 68, 68, 0.2);\n      border-radius: 8px;\n      padding: 1rem;\n      margin-top: 1rem;\n    }\n\n    .alert-box-title {\n      color: #f87171;\n      font-weight: 700;\n      font-size: 0.95rem;\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      margin-bottom: 0.5rem;\n    }\n\n    .alert-box-content {\n      font-size: 0.85rem;\n      line-height: 1.5;\n      color: var(--text-main);\n    }\n\n    .alert-box-content strong {\n      color: #fca5a5;\n    }\n  <\/style>\n<\/head>\n<body>\n\n<div class=\"container\">\n  <header>\n    <h1>Dijkstra&#8217;s Algorithm Visualizer<\/h1>\n    <p>Step-by-Step Graph Walkthrough for AlgoVelog<\/p>\n  <\/header>\n\n  <!-- Controls Panel -->\n  <div class=\"card controls-card\">\n    <div class=\"controls-wrapper\">\n      <div class=\"btn-group\">\n        <button id=\"btn-prev\" onclick=\"prevStep()\">\n          <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M15 18l-6-6 6-6\"\/><\/svg>\n          Prev\n        <\/button>\n        <button id=\"btn-play\" class=\"primary\" onclick=\"togglePlay()\">\n          <svg id=\"play-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n          <span id=\"play-text\">Play<\/span>\n        <\/button>\n        <button id=\"btn-next\" onclick=\"nextStep()\">\n          Next\n          <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M9 18l6-6-6-6\"\/><\/svg>\n        <\/button>\n        <button id=\"btn-reset\" onclick=\"resetVisualizer()\">\n          Reset\n        <\/button>\n      <\/div>\n\n      <div class=\"slider-container\">\n        <span class=\"slider-label\" id=\"step-label\">Step 1 \/ 7<\/span>\n        <input type=\"range\" id=\"step-slider\" min=\"0\" max=\"6\" value=\"0\" oninput=\"goToStep(parseInt(this.value))\">\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"visualizer-grid\">\n    <!-- Graph Canvas Card -->\n    <div class=\"card\">\n      <div class=\"card-title\">\n        <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"18\" cy=\"5\" r=\"3\"\/><circle cx=\"6\" cy=\"12\" r=\"3\"\/><circle cx=\"18\" cy=\"19\" r=\"3\"\/><path d=\"M9 12h6M9 12l6-5M9 12l6 7\"\/><\/svg>\n        Graph Layout\n      <\/div>\n      <div class=\"graph-container\">\n        <svg viewBox=\"0 0 600 400\" id=\"graph-svg\">\n          <!-- Edges (Rendered behind nodes) -->\n          <g id=\"edges-group\">\n            <!-- A-B (4) -->\n            <line id=\"edge-A-B\" class=\"edge\" x1=\"100\" y1=\"100\" x2=\"300\" y2=\"100\"><\/line>\n            <!-- A-C (2) -->\n            <line id=\"edge-A-C\" class=\"edge\" x1=\"100\" y1=\"100\" x2=\"100\" y2=\"300\"><\/line>\n            <!-- B-C (1) -->\n            <line id=\"edge-B-C\" class=\"edge\" x1=\"300\" y1=\"100\" x2=\"100\" y2=\"300\"><\/line>\n            <!-- B-D (5) -->\n            <line id=\"edge-B-D\" class=\"edge\" x1=\"300\" y1=\"100\" x2=\"500\" y2=\"100\"><\/line>\n            <!-- B-E (6) -->\n            <line id=\"edge-B-E\" class=\"edge\" x1=\"300\" y1=\"100\" x2=\"300\" y2=\"300\"><\/line>\n            <!-- C-D (8) -->\n            <line id=\"edge-C-D\" class=\"edge\" x1=\"100\" y1=\"300\" x2=\"500\" y2=\"100\"><\/line>\n            <!-- C-E (10) -->\n            <line id=\"edge-C-E\" class=\"edge\" x1=\"100\" y1=\"300\" x2=\"300\" y2=\"300\"><\/line>\n            <!-- D-E (2) -->\n            <line id=\"edge-D-E\" class=\"edge\" x1=\"500\" y1=\"100\" x2=\"300\" y2=\"300\"><\/line>\n          <\/g>\n\n          <!-- Edge Weight Labels -->\n          <g id=\"labels-group\">\n            <!-- A-B (4) -->\n            <g transform=\"translate(200, 100)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-A-B\" class=\"edge-label\">4<\/text>\n            <\/g>\n            <!-- A-C (2) -->\n            <g transform=\"translate(100, 200)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-A-C\" class=\"edge-label\">2<\/text>\n            <\/g>\n            <!-- B-C (1) -->\n            <g transform=\"translate(200, 200)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-B-C\" class=\"edge-label\">1<\/text>\n            <\/g>\n            <!-- B-D (5) -->\n            <g transform=\"translate(400, 100)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-B-D\" class=\"edge-label\">5<\/text>\n            <\/g>\n            <!-- B-E (6) -->\n            <g transform=\"translate(300, 200)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-B-E\" class=\"edge-label\">6<\/text>\n            <\/g>\n            <!-- C-D (8) -->\n            <g transform=\"translate(300, 200) translate(0, -35)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-C-D\" class=\"edge-label\">8<\/text>\n            <\/g>\n            <!-- C-E (10) -->\n            <g transform=\"translate(200, 300)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-C-E\" class=\"edge-label\">10<\/text>\n            <\/g>\n            <!-- D-E (2) -->\n            <g transform=\"translate(400, 200)\">\n              <rect class=\"edge-label-bg\" x=\"-12\" y=\"-12\" width=\"24\" height=\"24\"><\/rect>\n              <text id=\"weight-D-E\" class=\"edge-label\">2<\/text>\n            <\/g>\n          <\/g>\n\n          <!-- Nodes (Rendered on top) -->\n          <g id=\"nodes-group\">\n            <!-- Node A -->\n            <g id=\"node-A\" class=\"node\">\n              <circle class=\"node-circle\" cx=\"100\" cy=\"100\" r=\"24\"><\/circle>\n              <text class=\"node-text\" x=\"100\" y=\"100\">A<\/text>\n            <\/g>\n            <!-- Node B -->\n            <g id=\"node-B\" class=\"node\">\n              <circle class=\"node-circle\" cx=\"300\" cy=\"100\" r=\"24\"><\/circle>\n              <text class=\"node-text\" x=\"300\" y=\"100\">B<\/text>\n            <\/g>\n            <!-- Node C -->\n            <g id=\"node-C\" class=\"node\">\n              <circle class=\"node-circle\" cx=\"100\" cy=\"300\" r=\"24\"><\/circle>\n              <text class=\"node-text\" x=\"100\" y=\"300\">C<\/text>\n            <\/g>\n            <!-- Node D -->\n            <g id=\"node-D\" class=\"node\">\n              <circle class=\"node-circle\" cx=\"500\" cy=\"100\" r=\"24\"><\/circle>\n              <text class=\"node-text\" x=\"500\" y=\"100\">D<\/text>\n            <\/g>\n            <!-- Node E -->\n            <g id=\"node-E\" class=\"node\">\n              <circle class=\"node-circle\" cx=\"300\" cy=\"300\" r=\"24\"><\/circle>\n              <text class=\"node-text\" x=\"300\" y=\"300\">E<\/text>\n            <\/g>\n          <\/g>\n        <\/svg>\n      <\/div>\n    <\/div>\n\n    <!-- Algorithm State Card -->\n    <div class=\"card\">\n      <div class=\"card-title\">\n        <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><polyline points=\"14 2 14 8 20 8\"\/><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"\/><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"\/><polyline points=\"10 9 9 9 8 9\"\/><\/svg>\n        Step Execution &#038; State\n      <\/div>\n\n      <h3 id=\"step-title\" style=\"margin-bottom: 0.5rem; font-family: 'Outfit';\">Step 1: Initialization<\/h3>\n      <div id=\"step-description\" class=\"step-desc\">\n        Set the distance to the source node A to 0, and all other nodes to infinity (&infin;). Add the source node to the Priority Queue.\n      <\/div>\n\n      <!-- Visited Status -->\n      <div class=\"state-section\">\n        <div class=\"state-section-title\">Visited Nodes<\/div>\n        <div class=\"badge-list\" id=\"visited-container\">\n          <span class=\"text-muted\" style=\"font-size: 0.9rem;\">None yet<\/span>\n        <\/div>\n      <\/div>\n\n      <!-- Priority Queue Status -->\n      <div class=\"state-section\">\n        <div class=\"state-section-title\">Priority Queue (pq)<\/div>\n        <div class=\"badge-list\" id=\"pq-container\">\n          <!-- Badges dynamically added -->\n        <\/div>\n      <\/div>\n\n      <!-- Distance and Parent Table -->\n      <div class=\"state-section\">\n        <div class=\"state-section-title\">Node Distances &#038; Parents<\/div>\n        <div style=\"background: rgba(15, 23, 42, 0.3); border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.04); overflow: hidden;\">\n          <table>\n            <thead>\n              <tr>\n                <th>Node<\/th>\n                <th>Distance (dist)<\/th>\n                <th>Parent<\/th>\n              <\/tr>\n            <\/thead>\n            <tbody id=\"state-table-body\">\n              <!-- Dynamically populated -->\n            <\/tbody>\n          <\/table>\n        <\/div>\n      <\/div>\n      \n      <!-- Path reconstruction (Only on final step) -->\n      <div class=\"state-section\" id=\"final-path-section\" style=\"display: none;\">\n        <div class=\"state-section-title\">Path Reconstruction to E<\/div>\n        <div class=\"final-path-box\">\n          <div><strong>Reconstruction:<\/strong> E \u201a\u00dc\u00ea B \u201a\u00dc\u00ea C \u201a\u00dc\u00ea A<\/div>\n          <div><strong>Shortest Path:<\/strong> A \u201a\u00dc\u00ed C \u201a\u00dc\u00ed B \u201a\u00dc\u00ed E (Cost: 9)<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- Advantages, Limitations and Critical Requirements Section -->\n  <div class=\"info-grid\">\n    <!-- Advantages Card -->\n    <div class=\"card info-card-success\">\n      <div class=\"card-title\">\n        <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--color-success)\" stroke-width=\"2\"><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"\/><polyline points=\"22 4 12 14.01 9 11.01\"\/><\/svg>\n        Advantages &#038; Strengths\n      <\/div>\n      <ul class=\"info-list\">\n        <li>\n          <span class=\"icon\">\u201a\u00fa\u00d6<\/span>\n          <div><strong>Optimal solution guaranteed:<\/strong> Guaranteed for non-negative weights.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00fa\u00d6<\/span>\n          <div><strong>Single-source problem:<\/strong> Finds shortest paths to all vertices in one run.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00fa\u00d6<\/span>\n          <div><strong>Greedy approach:<\/strong> Greedy approach with proven correctness.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00fa\u00d6<\/span>\n          <div><strong>Efficient time complexity:<\/strong> Efficient O((V+E) log V) with binary heap.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00fa\u00d6<\/span>\n          <div><strong>Practical use:<\/strong> Practical and widely implemented in real systems.<\/div>\n        <\/li>\n      <\/ul>\n    <\/div>\n\n    <!-- Limitations Card -->\n    <div class=\"card info-card-warning\">\n      <div class=\"card-title\">\n        <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--color-danger)\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"\/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"\/><\/svg>\n        Limitations &#038; Constraints\n      <\/div>\n      <ul class=\"info-list\">\n        <li>\n          <span class=\"icon\">\u201a\u00f9\u00e5<\/span>\n          <div><strong>Non-negative weights only:<\/strong> Fails with negative edge weights.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00f9\u00e5<\/span>\n          <div><strong>All-pairs limitation:<\/strong> Not suitable for finding all-pairs shortest paths &#8211; use Floyd-Warshall for that.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00f9\u00e5<\/span>\n          <div><strong>Source-biased:<\/strong> Must run separately from each source.<\/div>\n        <\/li>\n        <li>\n          <span class=\"icon\">\u201a\u00f9\u00e5<\/span>\n          <div><strong>Dense graphs:<\/strong> O(V\u00ac\u2264) with linear search may be faster for very dense graphs.<\/div>\n        <\/li>\n      <\/ul>\n\n      <!-- Critical Requirement Alert -->\n      <div class=\"alert-box\">\n        <div class=\"alert-box-title\" style=\"color: #ef4444;\">\n          <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"\/><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"\/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"\/><\/svg>\n          Critical Requirement\n        <\/div>\n        <div class=\"alert-box-content\">\n          <p style=\"margin-bottom: 0.5rem; font-weight: 600;\">All edge weights MUST be non-negative. If even one negative edge exists, Dijkstra produces incorrect results.<\/p>\n          <p style=\"margin-bottom: 0.5rem; font-size: 0.8rem; color: var(--text-muted);\">\n            <strong>Why?<\/strong> Dijkstra&#8217;s proof of correctness relies on: once a vertex is finalized (marked as visited), its distance is optimal. With negative weights, a later-discovered path through a negative edge could make a &#8220;finalized&#8221; distance suboptimal. Dijkstra cannot backtrack to reconsider finalized vertices.\n          <\/p>\n          <p style=\"font-size: 0.8rem;\">\n            <strong>Alternative for negative weights:<\/strong> Use <strong>Bellman-Ford algorithm<\/strong> (O(VE) time, can detect negative cycles).\n          <\/p>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<script>\n  \/\/ Data defining each step of the Dijkstra run\n  const steps = [\n    {\n      title: \"Step 1: Initialization\",\n      desc: \"Initialize distance to source node A as 0, and all other nodes to infinity (&infin;). Add the pair (0, A) to the priority queue.\",\n      visited: [],\n      processing: null,\n      targets: [\"A\"],\n      dist: {A: \"0\", B: \"&infin;\", C: \"&infin;\", D: \"&infin;\", E: \"&infin;\"},\n      parent: {A: \"null\", B: \"null\", C: \"null\", D: \"null\", E: \"null\"},\n      pq: [\"(0, A)\"],\n      activeEdges: [],\n      updatingEdges: [],\n      shortestPathEdges: []\n    },\n    {\n      title: \"Step 2: Process A\",\n      desc: \"Extract (0, A) from the priority queue. Mark A as visited.<br>Explore A's neighbors:<br>\u201a\u00c4\u00a2 <strong>B:<\/strong> 0 + 4 = 4 &lt; &infin;. Update dist[B] = 4, parent[B] = A.<br>\u201a\u00c4\u00a2 <strong>C:<\/strong> 0 + 2 = 2 &lt; &infin;. Update dist[C] = 2, parent[C] = A.\",\n      visited: [\"A\"],\n      processing: \"A\",\n      targets: [\"B\", \"C\"],\n      dist: {A: \"0\", B: \"4\", C: \"2\", D: \"&infin;\", E: \"&infin;\"},\n      parent: {A: \"null\", B: \"A\", C: \"A\", D: \"null\", E: \"null\"},\n      pq: [\"(2, C)\", \"(4, B)\"],\n      activeEdges: [\"edge-A-B\", \"edge-A-C\"],\n      updatingEdges: [\"edge-A-B\", \"edge-A-C\"],\n      shortestPathEdges: []\n    },\n    {\n      title: \"Step 3: Process C\",\n      desc: \"Extract (2, C) from the priority queue. Mark C as visited.<br>Explore C's neighbors:<br>\u201a\u00c4\u00a2 <strong>A:<\/strong> Already visited, skip.<br>\u201a\u00c4\u00a2 <strong>B:<\/strong> 2 + 1 = 3 &lt; 4. Update dist[B] = 3, parent[B] = C.<br>\u201a\u00c4\u00a2 <strong>D:<\/strong> 2 + 8 = 10 &lt; &infin;. Update dist[D] = 10, parent[D] = C.<br>\u201a\u00c4\u00a2 <strong>E:<\/strong> 2 + 10 = 12 &lt; &infin;. Update dist[E] = 12, parent[E] = C.\",\n      visited: [\"A\", \"C\"],\n      processing: \"C\",\n      targets: [\"B\", \"D\", \"E\"],\n      dist: {A: \"0\", B: \"3\", C: \"2\", D: \"10\", E: \"12\"},\n      parent: {A: \"null\", B: \"C\", C: \"A\", D: \"C\", E: \"C\"},\n      pq: [\"(3, B)\", \"(4, B)\", \"(10, D)\", \"(12, E)\"],\n      activeEdges: [\"edge-A-C\", \"edge-B-C\", \"edge-C-D\", \"edge-C-E\"],\n      updatingEdges: [\"edge-B-C\", \"edge-C-D\", \"edge-C-E\"],\n      shortestPathEdges: []\n    },\n    {\n      title: \"Step 4: Process B\",\n      desc: \"Extract (3, B) from the priority queue. Mark B as visited.<br>Explore B's neighbors:<br>\u201a\u00c4\u00a2 <strong>A, C:<\/strong> Already visited, skip.<br>\u201a\u00c4\u00a2 <strong>D:<\/strong> 3 + 5 = 8 &lt; 10. Update dist[D] = 8, parent[D] = B.<br>\u201a\u00c4\u00a2 <strong>E:<\/strong> 3 + 6 = 9 &lt; 12. Update dist[E] = 9, parent[E] = B.\",\n      visited: [\"A\", \"C\", \"B\"],\n      processing: \"B\",\n      targets: [\"D\", \"E\"],\n      dist: {A: \"0\", B: \"3\", C: \"2\", D: \"8\", E: \"9\"},\n      parent: {A: \"null\", B: \"C\", C: \"A\", D: \"B\", E: \"B\"},\n      pq: [\"(4, B)\", \"(8, D)\", \"(9, E)\", \"(10, D)\", \"(12, E)\"],\n      activeEdges: [\"edge-A-C\", \"edge-B-C\", \"edge-B-D\", \"edge-B-E\"],\n      updatingEdges: [\"edge-B-D\", \"edge-B-E\"],\n      shortestPathEdges: []\n    },\n    {\n      title: \"Step 5: Process D\",\n      desc: \"Extract (4, B) from the priority queue. Since B is already visited, skip it.<br>Extract (8, D) from the priority queue. Mark D as visited.<br>Explore D's neighbors:<br>\u201a\u00c4\u00a2 <strong>B, C:<\/strong> Already visited, skip.<br>\u201a\u00c4\u00a2 <strong>E:<\/strong> 8 + 2 = 10 &gt; 9. No update is made since 9 is already shorter.\",\n      visited: [\"A\", \"C\", \"B\", \"D\"],\n      processing: \"D\",\n      targets: [\"E\"],\n      dist: {A: \"0\", B: \"3\", C: \"2\", D: \"8\", E: \"9\"},\n      parent: {A: \"null\", B: \"C\", C: \"A\", D: \"B\", E: \"B\"},\n      pq: [\"(9, E)\", \"(10, D)\", \"(12, E)\"],\n      activeEdges: [\"edge-A-C\", \"edge-B-C\", \"edge-B-D\", \"edge-B-E\", \"edge-D-E\"],\n      updatingEdges: [],\n      shortestPathEdges: []\n    },\n    {\n      title: \"Step 6: Process E\",\n      desc: \"Extract (9, E) from the priority queue. Mark E as visited.<br>E has no unvisited neighbors. The remaining elements in the priority queue will be skipped when extracted as their destinations are already visited.\",\n      visited: [\"A\", \"C\", \"B\", \"D\", \"E\"],\n      processing: \"E\",\n      targets: [],\n      dist: {A: \"0\", B: \"3\", C: \"2\", D: \"8\", E: \"9\"},\n      parent: {A: \"null\", B: \"C\", C: \"A\", D: \"B\", E: \"B\"},\n      pq: [],\n      activeEdges: [\"edge-A-C\", \"edge-B-C\", \"edge-B-D\", \"edge-B-E\"],\n      updatingEdges: [],\n      shortestPathEdges: []\n    },\n    {\n      title: \"Step 7: Final Result\",\n      desc: \"The algorithm has completed! The shortest paths are fully reconstructed. The shortest path from A to E is highlighted in blue: A \u201a\u00dc\u00ed C \u201a\u00dc\u00ed B \u201a\u00dc\u00ed E (Total cost = 9).\",\n      visited: [\"A\", \"C\", \"B\", \"D\", \"E\"],\n      processing: null,\n      targets: [],\n      dist: {A: \"0\", B: \"3\", C: \"2\", D: \"8\", E: \"9\"},\n      parent: {A: \"null\", B: \"C\", C: \"A\", D: \"B\", E: \"B\"},\n      pq: [],\n      activeEdges: [],\n      updatingEdges: [],\n      shortestPathEdges: [\"edge-A-C\", \"edge-B-C\", \"edge-B-E\"]\n    }\n  ];\n\n  let currentStep = 0;\n  let playInterval = null;\n  const playSpeed = 2500; \/\/ ms per step\n\n  \/\/ Initialize display\n  goToStep(0);\n\n  function goToStep(stepIndex) {\n    if (stepIndex < 0 || stepIndex >= steps.length) return;\n    \n    \/\/ Check if values updated from previous step to trigger animation\n    const oldStep = currentStep;\n    currentStep = stepIndex;\n    \n    document.getElementById(\"step-slider\").value = currentStep;\n    document.getElementById(\"step-label\").innerText = `Step ${currentStep + 1} \/ ${steps.length}`;\n    \n    \/\/ Update button states\n    document.getElementById(\"btn-prev\").disabled = (currentStep === 0);\n    document.getElementById(\"btn-next\").disabled = (currentStep === steps.length - 1);\n    \n    const stepData = steps[currentStep];\n    const prevStepData = oldStep !== currentStep ? steps[oldStep] : null;\n\n    \/\/ Update Text Content\n    document.getElementById(\"step-title\").innerText = stepData.title;\n    document.getElementById(\"step-description\").innerHTML = stepData.desc;\n    \n    const descDiv = document.getElementById(\"step-description\");\n    if (stepData.processing) {\n      descDiv.className = \"step-desc\";\n    } else if (stepData.visited.length === 5) {\n      descDiv.className = \"step-desc visited-update\";\n    } else {\n      descDiv.className = \"step-desc\";\n    }\n\n    \/\/ Update Visited Container\n    const visitedContainer = document.getElementById(\"visited-container\");\n    if (stepData.visited.length === 0) {\n      visitedContainer.innerHTML = `<span class=\"text-muted\" style=\"font-size: 0.9rem;\">None yet<\/span>`;\n    } else {\n      visitedContainer.innerHTML = stepData.visited.map(node => \n        `<span class=\"badge visited\">${node}<\/span>`\n      ).join(\"\");\n    }\n\n    \/\/ Update Priority Queue Container\n    const pqContainer = document.getElementById(\"pq-container\");\n    if (stepData.pq.length === 0) {\n      pqContainer.innerHTML = `<span class=\"text-muted\" style=\"font-size: 0.9rem;\">Empty<\/span>`;\n    } else {\n      pqContainer.innerHTML = stepData.pq.map(item => \n        `<span class=\"badge queue-item\">${item}<\/span>`\n      ).join(\"\");\n    }\n\n    \/\/ Populate Table\n    const tableBody = document.getElementById(\"state-table-body\");\n    tableBody.innerHTML = \"\";\n    [\"A\", \"B\", \"C\", \"D\", \"E\"].forEach(node => {\n      const distVal = stepData.dist[node];\n      const parentVal = stepData.parent[node];\n      \n      \/\/ Determine if this cell's values changed compared to previous step to highlight it\n      let distClass = \"val-cell\";\n      let parentClass = \"val-cell\";\n      if (prevStepData && prevStepData.dist[node] !== distVal) {\n        distClass += \" updated-val\";\n      }\n      if (prevStepData && prevStepData.parent[node] !== parentVal) {\n        parentClass += \" updated-val\";\n      }\n\n      const row = document.createElement(\"tr\");\n      row.innerHTML = `\n        <td style=\"font-weight: 600;\">Node ${node}<\/td>\n        <td class=\"${distClass}\">${distVal}<\/td>\n        <td class=\"${parentClass}\">${parentVal}<\/td>\n      `;\n      tableBody.appendChild(row);\n    });\n\n    \/\/ Toggle Final Path Section\n    const finalPathSection = document.getElementById(\"final-path-section\");\n    if (currentStep === steps.length - 1) {\n      finalPathSection.style.display = \"block\";\n    } else {\n      finalPathSection.style.display = \"none\";\n    }\n\n    \/\/ Update SVG Elements class names\n    \/\/ 1. Nodes\n    [\"A\", \"B\", \"C\", \"D\", \"E\"].forEach(nodeId => {\n      const nodeEl = document.getElementById(`node-${nodeId}`);\n      nodeEl.className.baseVal = \"node\"; \/\/ Reset\n      \n      if (stepData.processing === nodeId) {\n        nodeEl.className.baseVal = \"node processing\";\n      } else if (stepData.visited.includes(nodeId)) {\n        nodeEl.className.baseVal = \"node visited\";\n      } else if (stepData.targets.includes(nodeId)) {\n        nodeEl.className.baseVal = \"node target\";\n      }\n    });\n\n    \/\/ 2. Edges\n    const allEdges = [\"edge-A-B\", \"edge-A-C\", \"edge-B-C\", \"edge-B-D\", \"edge-B-E\", \"edge-C-D\", \"edge-C-E\", \"edge-D-E\"];\n    allEdges.forEach(edgeId => {\n      const edgeEl = document.getElementById(edgeId);\n      const labelId = edgeId.replace(\"edge\", \"weight\");\n      const labelEl = document.getElementById(labelId);\n      \n      edgeEl.className.baseVal = \"edge\"; \/\/ Reset\n      if (labelEl) labelEl.className.baseVal = \"edge-label\"; \/\/ Reset\n\n      if (stepData.shortestPathEdges.includes(edgeId)) {\n        edgeEl.className.baseVal = \"edge shortest-path\";\n        if (labelEl) labelEl.className.baseVal = \"edge-label active\";\n      } else if (stepData.updatingEdges.includes(edgeId)) {\n        edgeEl.className.baseVal = \"edge updating\";\n        if (labelEl) labelEl.className.baseVal = \"edge-label active\";\n      } else if (stepData.activeEdges.includes(edgeId)) {\n        edgeEl.className.baseVal = \"edge active\";\n        if (labelEl) labelEl.className.baseVal = \"edge-label active\";\n      }\n    });\n  }\n\n  function nextStep() {\n    if (currentStep < steps.length - 1) {\n      goToStep(currentStep + 1);\n    } else {\n      pause();\n    }\n  }\n\n  function prevStep() {\n    if (currentStep > 0) {\n      goToStep(currentStep - 1);\n    }\n  }\n\n  function resetVisualizer() {\n    pause();\n    goToStep(0);\n  }\n\n  function togglePlay() {\n    if (playInterval) {\n      pause();\n    } else {\n      play();\n    }\n  }\n\n  function play() {\n    if (currentStep === steps.length - 1) {\n      goToStep(0); \/\/ Loop back to start if at end\n    }\n    \n    document.getElementById(\"play-text\").innerText = \"Pause\";\n    \/\/ Change SVG to pause bars\n    document.getElementById(\"play-icon\").innerHTML = `<rect x=\"5\" y=\"4\" width=\"4\" height=\"16\"\/><rect x=\"15\" y=\"4\" width=\"4\" height=\"16\"\/>`;\n    \n    playInterval = setInterval(nextStep, playSpeed);\n  }\n\n  function pause() {\n    if (playInterval) {\n      clearInterval(playInterval);\n      playInterval = null;\n    }\n    document.getElementById(\"play-text\").innerText = \"Play\";\n    \/\/ Change SVG back to play triangle\n    document.getElementById(\"play-icon\").innerHTML = `<polygon points=\"5,3 19,12 5,21\"\/>`;\n  }\n<\/script>\n<\/body>\n<\/html>\n\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dijkstra&#8217;s Algorithm: A Comprehensive Guide Before directly jumping to Dijkstra&#8217;s Algorithm, let&#8217;s first understand some basic concepts related to it. Weighted Graph A weighted graph is a network of vertices (nodes) connected by edges, where each edge has a weight. The weight is a numerical value representing cost, distance, time, capacity, or any other metric [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-22","post","type-post","status-publish","format-standard","hentry","category-dsa"],"_links":{"self":[{"href":"https:\/\/algovelgo.com\/index.php?rest_route=\/wp\/v2\/posts\/22","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/algovelgo.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/algovelgo.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/algovelgo.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/algovelgo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=22"}],"version-history":[{"count":16,"href":"https:\/\/algovelgo.com\/index.php?rest_route=\/wp\/v2\/posts\/22\/revisions"}],"predecessor-version":[{"id":38,"href":"https:\/\/algovelgo.com\/index.php?rest_route=\/wp\/v2\/posts\/22\/revisions\/38"}],"wp:attachment":[{"href":"https:\/\/algovelgo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/algovelgo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/algovelgo.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}