Dijkstra's Algorithm
This content is not available in your language yet.
#include <compare>#include <iostream>#include <optional>#include <print>#include <ranges>#include <set>#include <vector>
class Edge {public: int toIdx; int weight;};
std::vector<std::optional<int>> shortestPaths(std::vector<std::vector<Edge>> const& graph, int startIdx) { class DijkstraState { public: int idx; int distance; };
auto compareState = [](auto const& state1, auto const& state2) -> bool { if (auto cmp = state1.distance <=> state2.distance; std::is_neq(cmp)) { return std::is_lt(cmp); } if (auto cmp = state1.idx <=> state2.idx; std::is_neq(cmp)) { return std::is_lt(cmp); } return 0; };
std::vector<std::optional<int>> distances(graph.size(), std::nullopt); distances[startIdx] = 0;
std::set<DijkstraState, decltype(compareState)> states {{startIdx, 0}};
while (!states.empty()) { auto curState = *states.begin(); states.erase(states.begin());
for (auto const& outEdge: graph[curState.idx]) { auto& currentBestDistance = distances[outEdge.toIdx]; int potentialDistance = curState.distance + outEdge.weight;
if (!currentBestDistance) { states.emplace(outEdge.toIdx, potentialDistance); currentBestDistance = potentialDistance; } else if (*currentBestDistance > potentialDistance) { auto nodeHandle = states.extract({outEdge.toIdx, *currentBestDistance}); currentBestDistance = potentialDistance; nodeHandle.value().distance = potentialDistance; states.insert(std::move(nodeHandle)).position; } } }
return distances;}
int main() { auto graph = std::vector<std::vector<Edge>> { {{3, 3}}, {{0, 5}, {2, 1}}, {{0, 2}, {3, 10}}, {}, {} };
auto distances = shortestPaths(graph, 1); for (auto const& [idx, distance]: distances | std::views::enumerate) { std::println("{}'s distance is {}", idx, distance ? *distance : -1); }}