{
    "slug": "dijkstra_algorithm",
    "term": "Dijkstra's Shortest Path Algorithm",
    "category": "algorithms",
    "difficulty": "advanced",
    "short": "A greedy graph algorithm that finds the shortest path from a source node to all other nodes in a weighted graph with non-negative edge weights.",
    "long": "Dijkstra's algorithm maintains a set of unvisited nodes and a distance table initialised to infinity for all nodes except the source (distance 0). At each step it picks the unvisited node with the smallest known distance, relaxes its neighbours (updates their distance if a shorter path is found via the current node), and marks it visited. With a min-heap (priority queue) the time complexity is O((V + E) log V) where V is vertices and E is edges. It cannot handle negative edge weights — use Bellman-Ford for those. Common applications: GPS navigation, network routing (OSPF), game pathfinding, and dependency resolution. In PHP it appears in graph-based recommendation engines, delivery route optimisation, and network topology tools.",
    "aliases": [
        "Dijkstra",
        "shortest path",
        "single-source shortest path",
        "SSSP"
    ],
    "tags": [
        "algorithms",
        "graphs",
        "pathfinding",
        "greedy",
        "computer-science"
    ],
    "misconception": "Dijkstra works with negative edge weights — it does not. Negative weights cause it to produce incorrect results because relaxing a node marks it permanently settled, but a later negative edge could produce a shorter path. Use Bellman-Ford or Johnson's algorithm instead.",
    "why_it_matters": "Shortest path problems appear constantly in real systems — routing, dependency graphs, game AI, and network analysis. Understanding Dijkstra gives you the foundation to reason about any weighted graph problem and the right instinct for when a priority queue is needed.",
    "common_mistakes": [
        "Using an array scan to find the minimum distance node instead of a min-heap — O(V²) instead of O((V+E) log V), catastrophic on large graphs.",
        "Not checking for negative weights before applying Dijkstra — silent wrong answers are worse than an exception.",
        "Revisiting already-settled nodes — always check if a node has been visited before processing it from the queue.",
        "Confusing Dijkstra with BFS — BFS finds shortest paths only in unweighted graphs; Dijkstra handles weighted edges."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "graph_algorithms",
        "a_star_algorithm",
        "big_o_notation",
        "spl_data_structures",
        "greedy_algorithms"
    ],
    "prerequisites": [
        "graph_algorithms",
        "big_o_notation",
        "data_structures"
    ],
    "refs": [
        "https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm"
    ],
    "bad_code": "// O(V²) — linear scan for minimum, no heap:\nfunction dijkstraSlow(array $graph, int $src): array {\n    $dist = array_fill(0, count($graph), PHP_INT_MAX);\n    $dist[$src] = 0;\n    $visited = [];\n    while (count($visited) < count($graph)) {\n        // Slow: scan all nodes to find min\n        $u = -1;\n        foreach ($dist as $v => $d) {\n            if (!isset($visited[$v]) && ($u === -1 || $d < $dist[$u])) $u = $v;\n        }\n        $visited[$u] = true;\n        foreach ($graph[$u] as [$v, $w]) {\n            if ($dist[$u] + $w < $dist[$v]) $dist[$v] = $dist[$u] + $w;\n        }\n    }\n    return $dist;\n}",
    "good_code": "// O((V+E) log V) — min-heap via SplMinHeap:\nfunction dijkstra(array $graph, int $src): array {\n    $dist = array_fill(0, count($graph), PHP_INT_MAX);\n    $dist[$src] = 0;\n    $heap = new SplMinHeap();\n    $heap->insert([0, $src]); // [distance, node]\n\n    while (!$heap->isEmpty()) {\n        [$d, $u] = $heap->extract();\n        if ($d > $dist[$u]) continue; // stale entry\n        foreach ($graph[$u] as [$v, $weight]) {\n            $newDist = $dist[$u] + $weight;\n            if ($newDist < $dist[$v]) {\n                $dist[$v] = $newDist;\n                $heap->insert([$newDist, $v]);\n            }\n        }\n    }\n    return $dist;\n}",
    "example_note": "The heap version skips stale queue entries with the `$d > $dist[$u]` guard, avoiding redundant processing.",
    "quick_fix": "Replace linear-scan minimum with SplMinHeap — reduces O(V²) to O((V+E) log V)",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-24",
    "updated": "2026-03-24",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/dijkstra_algorithm",
        "html_url": "https://codeclaritylab.com/glossary/dijkstra_algorithm",
        "json_url": "https://codeclaritylab.com/glossary/dijkstra_algorithm.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Dijkstra's Shortest Path Algorithm](https://codeclaritylab.com/glossary/dijkstra_algorithm) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/dijkstra_algorithm"
            }
        }
    }
}