Files
C-Plus-Plus/greedy_algorithms/dijkstra_greedy.cpp
realstealthninja 0d766b0f8a feat: update to CXX standard 17 and add CMakeLists file to directories without them (#2746)
* chore: add cache and build comment to git ignore

* fix: add cmakelists to dynamic programming

* fix: add cmakelists to greedy_algorithms

* fix: add cmakelists to operations_on_datastructures

* fix: add cmakelists to range_queries

* fix: add `dynamic_programmin`, `greedy_algorithms`, `range_queries` and `operations_on_datastructures` subdirectories to cmakelists.txt

* fix: init of transform_reduce in dynamic_programming

* fix: add an include for functional in catalan_numbers

* chore: bump CXX standard to 20

* revert: bump CXX standard to 20

* chore: bump c++ version to 17 and add justification

Arm supports c++ 17
Esp32 supports c++ 23
decision was made to be 17 because it seemed to offer the best combatability

* fix: compilation error in catalan numbers

* fix: add <set> header to longest increasing subsequence nlogn

* fix: add cmath & algorithm header to mo.cpp

* fix: remove register key word from fast integer

* fix: replace using namespace std with std::cin and std::cout

* docs: typo in c++17

* fix: memory leak in bellman_ford

* fix: typo in bellman_ford

* fix: typo in word_break

* fix: dynamic array in coin_change

* fix dynamic array in egg_dropping puzzle

* chore: remove unnecessary comment

* fix: add vla to be an error

* chore: add extra warnings

* fix: use add_compile options instead of set()

* fix: compile options are not strings

* fix: vla in floyd_warshall

* fix: vla in egg_dropping_puzzel

* fix: vla in coin_change

* fix: vla in edit_distance

* fix: vla in floyd_warshall

* feat: remove kadane and replace it with kadane2

* fix: vla in longest_common_subsequence

* fix: int overflow in floyd_warshall

* fix: vla in lisnlogn

* fix: use const vector& instead of array

* fix: use dynamic array instead of vla in knapsack

* fix: use of and in msvc is unsupported by default adding permissive flag fixes it

* test: make executables the tests themselves

* Revert "test: make executables the tests themselves"

This reverts commit 7a16c31c4e.

* fix: make dist constant in print

* fix: namespace issue in unbounded_0_1

* fix: include cstdint to fix compilation
2024-11-04 18:00:20 +05:30

203 lines
5.3 KiB
C++

/**
* @file
* @brief [Dijkstra](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) algorithm
* implementation
* @details
* _Quote from Wikipedia._
*
* **Dijkstra's algorithm** is an algorithm for finding the
* shortest paths between nodes in a weighted graph, which may represent, for
* example, road networks. It was conceived by computer scientist Edsger W.
* Dijkstra in 1956 and published three years later.
*
* @author [David Leal](https://github.com/Panquesito7)
* @author [Arpan Jain](https://github.com/arpanjain97)
*/
#include <cassert> /// for assert
#include <climits> /// for INT_MAX
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @namespace
* @brief Greedy Algorithms
*/
namespace greedy_algorithms {
/**
* @namespace
* @brief Functions for the [Dijkstra](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) algorithm implementation
*/
namespace dijkstra {
/**
* @brief Wrapper class for storing a graph
*/
class Graph {
public:
int vertexNum = 0;
std::vector<std::vector<int>> edges{};
/**
* @brief Constructs a graph
* @param V number of vertices of the graph
*/
explicit Graph(const int V) {
// Initialize the array edges
this->edges = std::vector<std::vector<int>>(V, std::vector<int>(V, 0));
for (int i = 0; i < V; i++) {
edges[i] = std::vector<int>(V, 0);
}
// Fills the array with zeros
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
edges[i][j] = 0;
}
}
this->vertexNum = V;
}
/**
* @brief Adds an edge to the graph
* @param src the graph the edge should be added to
* @param dst the position where the edge should be added to
* @param weight the weight of the edge that should be added
* @returns void
*/
void add_edge(int src, int dst, int weight) {
this->edges[src][dst] = weight;
}
};
/**
* @brief Utility function that finds
* the vertex with the minimum distance in `mdist`.
*
* @param mdist array of distances to each vertex
* @param vset array indicating inclusion in the shortest path tree
* @param V the number of vertices in the graph
* @returns index of the vertex with the minimum distance
*/
int minimum_distance(std::vector<int> mdist, std::vector<bool> vset, int V) {
int minVal = INT_MAX, minInd = 0;
for (int i = 0; i < V; i++) {
if (!vset[i] && (mdist[i] < minVal)) {
minVal = mdist[i];
minInd = i;
}
}
return minInd;
}
/**
* @brief Utility function to print the distances to vertices.
*
* This function prints the distances to each vertex in a tabular format. If the
* distance is equal to INT_MAX, it is displayed as "INF".
*
* @param dist An array representing the distances to each vertex.
* @param V The number of vertices in the graph.
* @return void
*/
void print(std::vector<int> dist, int V) {
std::cout << "\nVertex Distance\n";
for (int i = 0; i < V; i++) {
if (dist[i] < INT_MAX) {
std::cout << i << "\t" << dist[i] << "\n";
}
else {
std::cout << i << "\tINF" << "\n";
}
}
}
/**
* @brief The main function that finds the shortest path from a given source
* to all other vertices using Dijkstra's Algorithm.
* @note This doesn't work on negative weights.
* @param graph the graph to be processed
* @param src the source of the given vertex
* @returns void
*/
void dijkstra(Graph graph, int src) {
int V = graph.vertexNum;
std::vector<int> mdist{}; // Stores updated distances to the vertex
std::vector<bool> vset{}; // `vset[i]` is true if the vertex `i` is included in the shortest path tree
// Initialize `mdist and `vset`. Set the distance of the source as zero
for (int i = 0; i < V; i++) {
mdist[i] = INT_MAX;
vset[i] = false;
}
mdist[src] = 0;
// iterate to find the shortest path
for (int count = 0; count < V - 1; count++) {
int u = minimum_distance(mdist, vset, V);
vset[u] = true;
for (int v = 0; v < V; v++) {
if (!vset[v] && graph.edges[u][v] &&
mdist[u] + graph.edges[u][v] < mdist[v]) {
mdist[v] = mdist[u] + graph.edges[u][v];
}
}
}
print(mdist, V);
}
} // namespace dijkstra
} // namespace greedy_algorithms
/**
* @brief Self-test implementations
* @returns void
*/
static void tests() {
greedy_algorithms::dijkstra::Graph graph(8);
// 1st test.
graph.add_edge(6, 2, 4);
graph.add_edge(2, 6, 4);
assert(graph.edges[6][2] == 4);
// 2nd test.
graph.add_edge(0, 1, 1);
graph.add_edge(1, 0, 1);
assert(graph.edges[0][1] == 1);
// 3rd test.
graph.add_edge(0, 2, 7);
graph.add_edge(2, 0, 7);
graph.add_edge(1, 2, 1);
graph.add_edge(2, 1, 1);
assert(graph.edges[0][2] == 7);
// 4th test.
graph.add_edge(1, 3, 3);
graph.add_edge(3, 1, 3);
graph.add_edge(1, 4, 2);
graph.add_edge(4, 1, 2);
graph.add_edge(2, 3, 2);
assert(graph.edges[1][3] == 3);
std::cout << "All tests have successfully passed!\n";
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
tests(); // run self-test implementations
return 0;
}