{"id":329,"date":"2025-06-21T17:56:29","date_gmt":"2025-06-21T12:26:29","guid":{"rendered":"https:\/\/codeanddebug.in\/blog\/?p=329"},"modified":"2025-06-21T17:56:30","modified_gmt":"2025-06-21T12:26:30","slug":"dijkstra-algorithm-with-a-priority-queue","status":"publish","type":"post","link":"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/","title":{"rendered":"Dijkstra\u2019s Algorithm with a Priority Queue"},"content":{"rendered":"\n<p>Learn to implement Dijkstras Algorithm with a Priority Queue using a min-heap (heapq). We cover the problem statement, clear intuition, step-by-step approach, fully commented code, a hand dry-run, Big-O analysis, and key takeaways.<\/p>\n\n\n\n<p>Here&#8217;s the [<strong><a href=\"https:\/\/www.geeksforgeeks.org\/problems\/implementing-dijkstra-set-1-adjacency-matrix\/1\" target=\"_blank\" rel=\"noreferrer noopener\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><span style=\"text-decoration: underline;\">Problem Link<\/span><\/mark><\/a><\/strong>] to begin with.<\/p>\n\n\n<div style=\"max-width: -moz-fit-content; \" class=\"wp-block-ub-table-of-contents-block ub_table-of-contents ub_table-of-contents-collapsed\" id=\"ub_table-of-contents-051a4dc6-a4fc-4858-b59c-ebcd372a6d58\" data-linktodivider=\"false\" data-showtext=\"show\" data-hidetext=\"hide\" data-scrolltype=\"auto\" data-enablesmoothscroll=\"true\" data-initiallyhideonmobile=\"false\" data-initiallyshow=\"false\"><div class=\"ub_table-of-contents-header-container\" style=\"\">\n\t\t\t<div class=\"ub_table-of-contents-header\" style=\"text-align: left; \">\n\t\t\t\t<div class=\"ub_table-of-contents-title\">Contents:<\/div>\n\t\t\t\t<div class=\"ub_table-of-contents-header-toggle\">\n\t\t\t<div class=\"ub_table-of-contents-toggle\" style=\"\">\n\t\t\t\u00a0[<a class=\"ub_table-of-contents-toggle-link\" href=\"#\" style=\"\">show<\/a>]\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/div><div class=\"ub_table-of-contents-extra-container\" style=\"\">\n\t\t\t<div class=\"ub_table-of-contents-container ub_table-of-contents-1-column ub-hide\">\n\t\t\t\t<ul style=\"\"><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#0-1%E2%80%82what-does-the-problem-ask\" style=\"\">1\u2002What does the problem ask?<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#1-2%E2%80%82example\" style=\"\">2\u2002Example<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#2-3%E2%80%82deep-intuition-amp-approach-trainer-style\" style=\"\">3\u2002Deep intuition &amp; approach (trainer style)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#3-31%E2%80%82why-dijkstra-min-heap\" style=\"\">3.1\u2002Why Dijkstra + min-heap?<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#4-32%E2%80%82key-concepts\" style=\"\">3.2\u2002Key concepts<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#5-33%E2%80%82algorithm-outline\" style=\"\">3.3\u2002Algorithm outline<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#6-4%E2%80%82python-code-exact-lines-comments-added\" style=\"\">4\u2002Python code (exact lines, comments added)<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#7-5%E2%80%82step-by-step-code-explanation\" style=\"\">5\u2002Step-by-step code explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#8-6%E2%80%82dry-run-on-the-sample-graph\" style=\"\">6\u2002Dry run on the sample graph<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#9-7%E2%80%82complexity-analysis\" style=\"\">7\u2002Complexity analysis<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/dijkstra-algorithm-with-a-priority-queue\/#10-8%E2%80%82conclusion\" style=\"\">8\u2002Conclusion<\/a><\/li><\/ul>\n\t\t\t<\/div>\n\t\t<\/div><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"0-1%E2%80%82what-does-the-problem-ask\">1. What does the problem ask?<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>For a weighted <strong>directed<\/strong> graph with non-negative edge weights, return an array <code>dist<\/code> where<br><code>dist[i]<\/code> = length of the <strong>shortest path<\/strong> from a given source vertex <code>src<\/code> to vertex <code>i<\/code>.<br>If a vertex is unreachable, keep its distance as <code>\u221e<\/code> (or any sentinel like <code>float('inf')<\/code>).<\/p>\n<\/blockquote>\n\n\n\n<p>Although the original GFG statement shows an <em>adjacency matrix<\/em>, we\u2019ll solve with a more memory-friendly <strong>adjacency list<\/strong>; the core logic is identical.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1-2%E2%80%82example\">2. Example<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"V = 5, src = 0\nEdges = [\n  (0, 1, 4), (0, 2, 1),\n  (2, 1, 2), (1, 3, 1),\n  (2, 3, 5), (3, 4, 3)\n]\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">V = <\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">, src = <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">Edges = [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  (<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">), (<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  (<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">), (<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  (<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">), (<\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">3<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">]<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Shortest distances from <code>0<\/code> \u279c <code>[0, 3, 1, 4, 7]<\/code><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>0 \u2192 2 (1) \u2192 1 ( + 2) = <strong>3<\/strong><\/li>\n\n\n\n<li>0 \u2192 2 (1) \u2192 1 (2) \u2192 3 ( + 1) = <strong>4<\/strong><\/li>\n\n\n\n<li>0 \u2192 2 \u2192 1 \u2192 3 \u2192 4 totals <strong>7<\/strong><\/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\" id=\"2-3%E2%80%82deep-intuition-amp-approach-trainer-style\">3. Deep intuition &amp; approach <\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"3-31%E2%80%82why-dijkstra-min-heap\">3.1\u2002Why Dijkstra + min-heap?<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A <strong>greedy<\/strong> idea underlies the algorithm:<br><em>Among all unexplored vertices, pick the one with the currently smallest tentative distance; lock that distance forever.<\/em><\/li>\n\n\n\n<li>A <strong>priority queue<\/strong> (min-heap) lets us pop that \u201clightest\u201d vertex in <code>O(log V)<\/code> time.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"4-32%E2%80%82key-concepts\">3.2\u2002Key concepts<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Distance array<\/strong> \u2013 our best-so-far estimates.<\/li>\n\n\n\n<li><strong>Visited \/ relaxed rule<\/strong> \u2013 once we pop a vertex from the heap, its distance is <strong>final<\/strong>; no shorter path can appear later because all remaining paths are already heavier.<\/li>\n\n\n\n<li><strong>Edge relaxation<\/strong> \u2013 for each edge <code>u \u2192 v<\/code> with weight <code>w<\/code>: pythonCopyEdit<code>if dist[u] + w &lt; dist[v]: dist[v] = dist[u] + w push (dist[v], v) into heap<\/code> This may insert multiple copies of <code>v<\/code>, but only the one with the smallest distance will matter when popped.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"5-33%E2%80%82algorithm-outline\">3.3\u2002Algorithm outline<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Build adjacency list<\/strong> from the edge list \/ matrix.<\/li>\n\n\n\n<li>Initialise <code>dist[src] = 0<\/code>, everything else <code>\u221e<\/code>.<\/li>\n\n\n\n<li>Push <code>(0, src)<\/code> into a <strong>min-heap<\/strong>.<\/li>\n\n\n\n<li><strong>Loop while heap not empty:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Pop <code>(currDist, u)<\/code> (the lightest vertex).<\/li>\n\n\n\n<li>For every neighbour <code>(v, w)<\/code> of <code>u<\/code>, relax the edge.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Heap eventually empties, leaving <code>dist<\/code> filled with final shortest paths.<\/li>\n<\/ol>\n\n\n\n<p>Because edge weights are non-negative, the greedy choice is safe; negative weights would break Dijkstra.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6-4%E2%80%82python-code-exact-lines-comments-added\">4. Python code<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"import heapq\n\nclass Solution:\n    # Returns shortest distances from src to all other vertices\n    def dijkstra(self, V, edges, src):\n        # -------- 1. Build adjacency list --------\n        adj_list = [[] for _ in range(V)]\n        for u, v, d in edges:\n            adj_list[u].append([v, d])\n\n        # -------- 2. Distance + heap initialisation --------\n        distance = [float(&quot;inf&quot;) for _ in range(V)]\n        distance[src] = 0\n        priority_queue = [[0, src]]          # (dist, vertex)\n\n        # -------- 3. Main loop --------\n        while priority_queue:\n            curr_dist, node = heapq.heappop(priority_queue)\n\n            # Skip stale entries\n            if curr_dist != distance[node]:\n                continue\n\n            # Explore neighbours\n            for adjNode, weight in adj_list[node]:\n                dist_trav = curr_dist + weight\n                if dist_trav &lt; distance[adjNode]:\n                    distance[adjNode] = dist_trav\n                    heapq.heappush(priority_queue, [dist_trav, adjNode])\n\n        return distance\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> heapq<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #6A9955\"># Returns shortest distances from src to all other vertices<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">dijkstra<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">V<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">edges<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">src<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># -------- 1. Build adjacency list --------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        adj_list = [[] <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> _ <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(V)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> u, v, d <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> edges:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            adj_list[u].append([v, d])<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># -------- 2. Distance + heap initialisation --------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        distance = [<\/span><span style=\"color: #4EC9B0\">float<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;inf&quot;<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> _ <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">range<\/span><span style=\"color: #D4D4D4\">(V)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        distance[src] = <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        priority_queue = [[<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, src]]          <\/span><span style=\"color: #6A9955\"># (dist, vertex)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># -------- 3. Main loop --------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> priority_queue:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            curr_dist, node = heapq.heappop(priority_queue)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #6A9955\"># Skip stale entries<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> curr_dist != distance[node]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">continue<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #6A9955\"># Explore neighbours<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> adjNode, weight <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> adj_list[node]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                dist_trav = curr_dist + weight<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> dist_trav &lt; distance[adjNode]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    distance[adjNode] = dist_trav<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    heapq.heappush(priority_queue, [dist_trav, adjNode])<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> distance<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7-5%E2%80%82step-by-step-code-explanation\">5. Step-by-step code explanation<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Line(s)<\/th><th>What happens<\/th><th>Why it matters<\/th><\/tr><\/thead><tbody><tr><td><strong>4-6<\/strong><\/td><td>Create <code>adj_list<\/code>: <code>adj_list[u]<\/code> holds pairs <code>[v, w]<\/code>.<\/td><td>Faster than scanning an entire matrix.<\/td><\/tr><tr><td><strong>9-11<\/strong><\/td><td><code>distance<\/code> starts as <code>\u221e<\/code>; <code>src<\/code> is <code>0<\/code>. Heap seeded with <code>(0, src)<\/code>.<\/td><td>First vertex has zero cost to itself.<\/td><\/tr><tr><td><strong>14<\/strong><\/td><td>Pop the vertex with the current smallest distance.<\/td><td>Ensures greedy property.<\/td><\/tr><tr><td><strong>17-18<\/strong><\/td><td><em>Stale entry check<\/em>: if we previously found a shorter path to <code>node<\/code>, skip this outdated heap entry.<\/td><td>Avoids extra processing.<\/td><\/tr><tr><td><strong>21-25<\/strong><\/td><td>For every neighbour, compute new tentative distance. If it improves <code>distance[adjNode]<\/code>, update and push the pair.<\/td><td>Standard <strong>edge relaxation<\/strong>.<\/td><\/tr><tr><td><strong>24<\/strong><\/td><td>Push even if <code>adjNode<\/code> already exists in heap.<\/td><td>Heap keeps multiple copies; stale ones are ignored later by line 17.<\/td><\/tr><tr><td><strong>26<\/strong><\/td><td>After heap empties, <code>distance<\/code> holds final answers.<\/td><td>Heap empties when all reachable vertices are locked.<\/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\" id=\"8-6%E2%80%82dry-run-on-the-sample-graph\">6. Dry run on the sample graph<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Heap (min at left)<\/th><th>Popped <code>(dist, u)<\/code><\/th><th>Relaxations &amp; updates<\/th><th>Final <code>distance<\/code> so far<\/th><\/tr><\/thead><tbody><tr><td><code>[(0,0)]<\/code><\/td><td><code>(0,0)<\/code><\/td><td><code>1\u21924<\/code>, <code>2\u21921<\/code><\/td><td><code>[0,4,1,\u221e,\u221e]<\/code><\/td><\/tr><tr><td><code>[(1,2),(4,1)]<\/code><\/td><td><code>(1,2)<\/code><\/td><td>2\u21921 improves to 3; 2\u21923 to 6<\/td><td><code>[0,3,1,6,\u221e]<\/code><\/td><\/tr><tr><td><code>[(3,1),(4,1),(6,3)]<\/code> (note: two (1) copies)<\/td><td><code>(3,1)<\/code><\/td><td>1\u21923 improves to 4<\/td><td><code>[0,3,1,4,\u221e]<\/code><\/td><\/tr><tr><td><code>[(4,1),(6,3)]<\/code><\/td><td><code>(4,1)<\/code> <em>stale<\/em> skip<\/td><td>\u2013<\/td><td>same<\/td><\/tr><tr><td><code>[(4,3)]<\/code><\/td><td><code>(4,3)<\/code><\/td><td>3\u21924 to 7<\/td><td><code>[0,3,1,4,7]<\/code><\/td><\/tr><tr><td>Heap empty<\/td><td>\u2013<\/td><td>\u2013<\/td><td>done<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Distances match expected output <code>[0, 3, 1, 4, 7]<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9-7%E2%80%82complexity-analysis\">7. Complexity analysis<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Metric<\/th><th>Value<\/th><\/tr><\/thead><tbody><tr><td><strong>Time<\/strong><\/td><td><strong>O((V + E) log V)<\/strong> \u2013 each <code>heappop<\/code> \/ <code>heappush<\/code> costs <code>log V<\/code>.<\/td><\/tr><tr><td><strong>Space<\/strong><\/td><td><strong>O(V + E)<\/strong> \u2013 adjacency list + distance array + heap (worst case holds all vertices).<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>For sparse graphs this is significantly faster than using an adjacency matrix with <code>O(V\u00b2)<\/code> scanning.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"10-8%E2%80%82conclusion\">8. Conclusion<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Priority-queue Dijkstra<\/strong> elegantly handles non-negative weighted graphs.<\/li>\n\n\n\n<li>The min-heap pops the next <em>safest<\/em> vertex, guaranteeing its distance is final.<\/li>\n\n\n\n<li>Edge relaxation then spreads improvements to neighbours.<\/li>\n\n\n\n<li>Remember the <em>stale-entry<\/em> guard to avoid unnecessary relaxations when a better path has already been recorded.<\/li>\n<\/ul>\n\n\n\n<p>With these principles and the commented code above, you can confidently apply Dijkstra to real-world shortest-path problems.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-16018d1d wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.codeanddebug.in\/course\/zero-to-hero-python-dsa\">Join our Advance DSA COURSE<\/a><\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><em>For any changes to the article, kindly email at <a href=\"mailto:code@codeanddebug.in\">code@codeanddebug.in<\/a> or contact us at <a href=\"tel:+91-9712928220\">+91-9712928220<\/a>.<\/em><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn to implement Dijkstras Algorithm with a Priority Queue using a min-heap (heapq). We cover the problem statement, clear intuition, step-by-step approach, fully commented code, a hand dry-run, Big-O analysis, and key takeaways. Here&#8217;s the [Problem Link] to begin with. 1. What does the problem ask? For a weighted directed graph with non-negative edge weights,<\/p>\n","protected":false},"author":1,"featured_media":331,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,6],"tags":[24,17],"class_list":{"0":"post-329","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-data-structures-and-algorithm","8":"category-intermediate","9":"tag-dijkstra-algorithm","10":"tag-graph"},"featured_image_src":"https:\/\/codeanddebug.in\/blog\/wp-content\/uploads\/2025\/06\/dijkstra-algorithm-using-priority-queue-featured-image.png","author_info":{"display_name":"codeanddebug","author_link":"https:\/\/codeanddebug.in\/blog\/author\/codeanddebug\/"},"_links":{"self":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/329","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/comments?post=329"}],"version-history":[{"count":1,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/329\/revisions"}],"predecessor-version":[{"id":332,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/329\/revisions\/332"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/media\/331"}],"wp:attachment":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/media?parent=329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/categories?post=329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/tags?post=329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}