From 4c9aaf95e769cb267e171d704453741b5af2428c Mon Sep 17 00:00:00 2001 From: sonicdashh <147204439+sonicdashh@users.noreply.github.com> Date: Fri, 6 Oct 2023 20:46:11 +0000 Subject: [PATCH 1/2] =?UTF-8?q?Added=20the=20implementations=20of=20Depth?= =?UTF-8?q?=5FFirst=5FSearch,=20Breadth=5FFirst=5FSearch=E2=80=A6=20?= =?UTF-8?q?=E2=80=A6,BellmanFord=5FAlgo=20,=20Floyyd=5FWarshall=5FAlgo=20,?= =?UTF-8?q?=20KruskalAlgo=20,=20MergeSort=20,=20Prims=5FAlgo=20,Topologica?= =?UTF-8?q?lSort=20,DSU=5FTemplate=20among=20others.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Graph_Algorithms/BellmanFord.cpp | 82 +++++++++++++++++++++++++++ Graph_Algorithms/DSU.cpp | 56 +++++++++++++++++++ Graph_Algorithms/Dijkstra.cpp | 80 +++++++++++++++++++++++++++ Graph_Algorithms/Floyyd_Warshall.cpp | 67 ++++++++++++++++++++++ Graph_Algorithms/Kruskal.cpp | 83 ++++++++++++++++++++++++++++ Graph_Algorithms/Prims_Algo.cpp | 74 +++++++++++++++++++++++++ 6 files changed, 442 insertions(+) create mode 100644 Graph_Algorithms/BellmanFord.cpp create mode 100644 Graph_Algorithms/DSU.cpp create mode 100644 Graph_Algorithms/Dijkstra.cpp create mode 100644 Graph_Algorithms/Floyyd_Warshall.cpp create mode 100644 Graph_Algorithms/Kruskal.cpp create mode 100644 Graph_Algorithms/Prims_Algo.cpp diff --git a/Graph_Algorithms/BellmanFord.cpp b/Graph_Algorithms/BellmanFord.cpp new file mode 100644 index 0000000..d9683ba --- /dev/null +++ b/Graph_Algorithms/BellmanFord.cpp @@ -0,0 +1,82 @@ +#include +#include +#include + +using namespace std; + +const int INF = INT_MAX; + +struct Edge { + int src, dest, weight; +}; + +class Graph { +public: + int V, E; // Number of vertices and edges + vector edges; + + Graph(int vertices, int edgesCount) { + V = vertices; + E = edgesCount; + edges.resize(E); + } + + void addEdge(int u, int v, int w, int edgeIndex) { + edges[edgeIndex].src = u; + edges[edgeIndex].dest = v; + edges[edgeIndex].weight = w; + } + + void bellmanFord(int src) { + vector dist(V, INF); + dist[src] = 0; + + for (int i = 0; i < V - 1; i++) { + for (int j = 0; j < E; j++) { + int u = edges[j].src; + int v = edges[j].dest; + int weight = edges[j].weight; + + if (dist[u] != INF && dist[u] + weight < dist[v]) { + dist[v] = dist[u] + weight; + } + } + } + + // Check for negative-weight cycles + for (int j = 0; j < E; j++) { + int u = edges[j].src; + int v = edges[j].dest; + int weight = edges[j].weight; + + if (dist[u] != INF && dist[u] + weight < dist[v]) { + cout << "Negative-weight cycle detected!" << endl; + return; + } + } + + cout << "Shortest distances from vertex " << src << ":\n"; + for (int i = 0; i < V; i++) { + cout << "Vertex " << i << ": " << dist[i] << "\n"; + } + } +}; + +int main() { + int V, E; // Number of vertices and edges + cin >> V >> E; + Graph g(V, E); + + for (int i = 0; i < E; i++) { + int u, v, w; + cin >> u >> v >> w; + g.addEdge(u, v, w, i); + } + + int src; // Source vertex for Bellman-Ford + cin >> src; + + g.bellmanFord(src); + + return 0; +} diff --git a/Graph_Algorithms/DSU.cpp b/Graph_Algorithms/DSU.cpp new file mode 100644 index 0000000..7db8883 --- /dev/null +++ b/Graph_Algorithms/DSU.cpp @@ -0,0 +1,56 @@ +#include +#include + +using namespace std; + +class DSU { +public: + vector parent, rank; + + DSU(int n) { + parent.resize(n); + rank.resize(n, 0); + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + int find(int x) { + if (x != parent[x]) { + parent[x] = find(parent[x]); + } + return parent[x]; + } + + void unionSets(int x, int y) { + int rootX = find(x); + int rootY = find(y); + + if (rootX != rootY) { + if (rank[rootX] < rank[rootY]) { + parent[rootX] = rootY; + } else if (rank[rootX] > rank[rootY]) { + parent[rootY] = rootX; + } else { + parent[rootY] = rootX; + rank[rootX]++; + } + } + } +}; + +int main() { + int n; // Number of elements + cin >> n; + DSU dsu(n); + + // Example usage: unionSets and find operations + dsu.unionSets(0, 1); + dsu.unionSets(2, 3); + dsu.unionSets(0, 3); + + cout << "Are 1 and 2 in the same set? " << (dsu.find(1) == dsu.find(2) ? "Yes" : "No") << endl; + cout << "Are 0 and 3 in the same set? " << (dsu.find(0) == dsu.find(3) ? "Yes" : "No") << endl; + + return 0; +} diff --git a/Graph_Algorithms/Dijkstra.cpp b/Graph_Algorithms/Dijkstra.cpp new file mode 100644 index 0000000..c9c5c69 --- /dev/null +++ b/Graph_Algorithms/Dijkstra.cpp @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +using namespace std; + +const int INF = INT_MAX; + +// Define a class to represent a weighted graph +class Graph { +public: + int V; // Number of vertices + vector>> adj; // Adjacency list + + Graph(int vertices) { + V = vertices; + adj.resize(V); + } + + // Function to add an edge to the graph + void addEdge(int u, int v, int w) { + adj[u].push_back({v, w}); + adj[v].push_back({u, w}); // If the graph is undirected + } + + // Dijkstra's algorithm to find the shortest path + vector dijkstra(int src) { + vector dist(V, INF); + dist[src] = 0; + + priority_queue, vector>, greater>> pq; + pq.push({0, src}); + + while (!pq.empty()) { + int u = pq.top().second; + int weight = pq.top().first; + pq.pop(); + + if (weight > dist[u]) continue; + + for (pair& edge : adj[u]) { + int v = edge.first; + int w = edge.second; + + if (dist[u] + w < dist[v]) { + dist[v] = dist[u] + w; + pq.push({dist[v], v}); + } + } + } + + return dist; + } +}; + +int main() { + int V, E; // Number of vertices and edges + cin >> V >> E; + + Graph g(V); + + for (int i = 0; i < E; i++) { + int u, v, w; + cin >> u >> v >> w; + g.addEdge(u, v, w); + } + + int src; // Source vertex for Dijkstra's algorithm + cin >> src; + + vector shortestDistances = g.dijkstra(src); + + cout << "Shortest distances from vertex " << src << ":\n"; + for (int i = 0; i < V; i++) { + cout << "Vertex " << i << ": " << shortestDistances[i] << "\n"; + } + + return 0; +} diff --git a/Graph_Algorithms/Floyyd_Warshall.cpp b/Graph_Algorithms/Floyyd_Warshall.cpp new file mode 100644 index 0000000..fc6511e --- /dev/null +++ b/Graph_Algorithms/Floyyd_Warshall.cpp @@ -0,0 +1,67 @@ +#include +#include +#include + +using namespace std; + +const int INF = INT_MAX; + +class Graph { +public: + int V; // Number of vertices + vector> dist; + + Graph(int vertices) { + V = vertices; + dist.resize(V, vector(V, INF)); + + // Initialize diagonal elements to 0 + for (int i = 0; i < V; i++) { + dist[i][i] = 0; + } + } + + void addEdge(int u, int v, int w) { + dist[u][v] = w; + } + + void floydWarshall() { + for (int k = 0; k < V; k++) { + for (int i = 0; i < V; i++) { + for (int j = 0; j < V; j++) { + if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) { + dist[i][j] = dist[i][k] + dist[k][j]; + } + } + } + } + + cout << "Shortest distances between all pairs of vertices:\n"; + for (int i = 0; i < V; i++) { + for (int j = 0; j < V; j++) { + if (dist[i][j] == INF) { + cout << "INF "; + } else { + cout << dist[i][j] << " "; + } + } + cout << "\n"; + } + } +}; + +int main() { + int V, E; // Number of vertices and edges + cin >> V >> E; + Graph g(V); + + for (int i = 0; i < E; i++) { + int u, v, w; + cin >> u >> v >> w; + g.addEdge(u, v, w); + } + + g.floydWarshall(); + + return 0; +} diff --git a/Graph_Algorithms/Kruskal.cpp b/Graph_Algorithms/Kruskal.cpp new file mode 100644 index 0000000..0a1cb31 --- /dev/null +++ b/Graph_Algorithms/Kruskal.cpp @@ -0,0 +1,83 @@ +#include +#include +#include + +using namespace std; + +struct Edge { + int u, v, weight; +}; + +bool compareEdges(const Edge& a, const Edge& b) { + return a.weight < b.weight; +} + +class UnionFind { +public: + vector parent, rank; + + UnionFind(int n) { + parent.resize(n); + rank.resize(n, 0); + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + int find(int x) { + if (x != parent[x]) { + parent[x] = find(parent[x]); + } + return parent[x]; + } + + void unionSets(int x, int y) { + int rootX = find(x); + int rootY = find(y); + + if (rootX != rootY) { + if (rank[rootX] < rank[rootY]) { + parent[rootX] = rootY; + } else if (rank[rootX] > rank[rootY]) { + parent[rootY] = rootX; + } else { + parent[rootY] = rootX; + rank[rootX]++; + } + } + } +}; + +vector kruskalMST(vector& edges, int n) { + sort(edges.begin(), edges.end(), compareEdges); + vector minimumSpanningTree; + UnionFind uf(n); + + for (Edge edge : edges) { + if (uf.find(edge.u) != uf.find(edge.v)) { + minimumSpanningTree.push_back(edge); + uf.unionSets(edge.u, edge.v); + } + } + + return minimumSpanningTree; +} + +int main() { + int n, m; // Number of vertices and edges + cin >> n >> m; + vector edges(m); + + for (int i = 0; i < m; i++) { + cin >> edges[i].u >> edges[i].v >> edges[i].weight; + } + + vector minimumSpanningTree = kruskalMST(edges, n); + + cout << "Minimum Spanning Tree Edges:\n"; + for (Edge edge : minimumSpanningTree) { + cout << edge.u << " - " << edge.v << " : " << edge.weight << "\n"; + } + + return 0; +} diff --git a/Graph_Algorithms/Prims_Algo.cpp b/Graph_Algorithms/Prims_Algo.cpp new file mode 100644 index 0000000..48e562c --- /dev/null +++ b/Graph_Algorithms/Prims_Algo.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +using namespace std; + +const int INF = INT_MAX; + +class Graph { +public: + int V; // Number of vertices + vector>> adj; // Adjacency list + + Graph(int vertices) { + V = vertices; + adj.resize(V); + } + + void addEdge(int u, int v, int w) { + adj[u].push_back({v, w}); + adj[v].push_back({u, w}); + } + + int primMST() { + priority_queue, vector>, greater>> pq; + vector key(V, INF); + vector inMST(V, false); + + int src = 0; // Start from vertex 0 + pq.push({0, src}); + key[src] = 0; + + while (!pq.empty()) { + int u = pq.top().second; + pq.pop(); + inMST[u] = true; + + for (pair& edge : adj[u]) { + int v = edge.first; + int weight = edge.second; + + if (!inMST[v] && weight < key[v]) { + key[v] = weight; + pq.push({key[v], v}); + } + } + } + + int minimumCost = 0; + for (int i = 0; i < V; i++) { + minimumCost += key[i]; + } + + return minimumCost; + } +}; + +int main() { + int V, E; // Number of vertices and edges + cin >> V >> E; + Graph g(V); + + for (int i = 0; i < E; i++) { + int u, v, w; + cin >> u >> v >> w; + g.addEdge(u, v, w); + } + + int minimumCost = g.primMST(); + cout << "Minimum Cost of MST: " << minimumCost << endl; + + return 0; +} From c1d3d2319e7f0d1b57ca2d0237b606d43c795621 Mon Sep 17 00:00:00 2001 From: sonicdashh <147204439+sonicdashh@users.noreply.github.com> Date: Sun, 8 Oct 2023 10:41:23 +0000 Subject: [PATCH 2/2] Added descriptions to various graph algo codes . --- Graph_Algorithms/BellmanFord.cpp | 3 +++ Graph_Algorithms/DSU.cpp | 2 ++ Graph_Algorithms/Dijkstra.cpp | 4 ++++ Graph_Algorithms/Floyyd_Warshall.cpp | 3 +++ Graph_Algorithms/Kruskal.cpp | 3 +++ Graph_Algorithms/Prims_Algo.cpp | 3 +++ 6 files changed, 18 insertions(+) diff --git a/Graph_Algorithms/BellmanFord.cpp b/Graph_Algorithms/BellmanFord.cpp index d9683ba..b6bb2e9 100644 --- a/Graph_Algorithms/BellmanFord.cpp +++ b/Graph_Algorithms/BellmanFord.cpp @@ -1,3 +1,6 @@ +// This algorithm is used to find the shortest path from a single source vertex to all other vertices, even in the presence of negative weight edges. It can detect negative weight cycles. + + #include #include #include diff --git a/Graph_Algorithms/DSU.cpp b/Graph_Algorithms/DSU.cpp index 7db8883..7ab766e 100644 --- a/Graph_Algorithms/DSU.cpp +++ b/Graph_Algorithms/DSU.cpp @@ -1,3 +1,5 @@ +//DSU is a data structure used to manage a partition of a set into disjoint subsets. It supports operations like union (merging two subsets) and find (finding the representative element of a subset). + #include #include diff --git a/Graph_Algorithms/Dijkstra.cpp b/Graph_Algorithms/Dijkstra.cpp index c9c5c69..b9640bb 100644 --- a/Graph_Algorithms/Dijkstra.cpp +++ b/Graph_Algorithms/Dijkstra.cpp @@ -1,3 +1,7 @@ + +// Dijkstra's algorithm is a widely used algorithm for finding the shortest path from a single source vertex to all other vertices in a weighted graph. It's particularly useful for graphs with non-negative edge weights. + + #include #include #include diff --git a/Graph_Algorithms/Floyyd_Warshall.cpp b/Graph_Algorithms/Floyyd_Warshall.cpp index fc6511e..744b662 100644 --- a/Graph_Algorithms/Floyyd_Warshall.cpp +++ b/Graph_Algorithms/Floyyd_Warshall.cpp @@ -1,3 +1,6 @@ +// Floyd-Warshall is an all-pairs shortest path algorithm. It computes the shortest paths between all pairs of vertices in a weighted graph, including negative weight edges. + + #include #include #include diff --git a/Graph_Algorithms/Kruskal.cpp b/Graph_Algorithms/Kruskal.cpp index 0a1cb31..e598922 100644 --- a/Graph_Algorithms/Kruskal.cpp +++ b/Graph_Algorithms/Kruskal.cpp @@ -1,3 +1,6 @@ + +//Kruskal's algorithm is used to find the Minimum Spanning Tree (MST) of a connected, undirected graph. It does this by selecting edges with the smallest weight while avoiding cycles. + #include #include #include diff --git a/Graph_Algorithms/Prims_Algo.cpp b/Graph_Algorithms/Prims_Algo.cpp index 48e562c..ca12b23 100644 --- a/Graph_Algorithms/Prims_Algo.cpp +++ b/Graph_Algorithms/Prims_Algo.cpp @@ -1,3 +1,6 @@ + +//Prim's algorithm is another approach to find the Minimum Spanning Tree (MST). It starts with an arbitrary vertex and grows the MST one vertex at a time by selecting the edge with the minimum weight. + #include #include #include