Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Bellman ford and Koseraju Algorithm in C++ Section. #577

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions C++program/Bellman-Ford.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <bits/stdc++.h>
using namespace std;

// a structure to represent a weighted edge in graph
struct Edge
{
int src, dest, weight;
};

// a structure to represent a connected, directed and
// weighted graph
struct Graph
{
// V-> Number of vertices, E-> Number of edges
int V, E;

// graph is represented as an array of edges.
struct Edge *edge;
};

// Creates a graph with V vertices and E edges
struct Graph *createGraph(int V, int E)
{
struct Graph *graph = new Graph;
graph->V = V;
graph->E = E;
graph->edge = new Edge[E];
return graph;
}

// A utility function used to print the solution
void printArr(int dist[], int n)
{
printf("Vertex Distance from Source\n");
for (int i = 0; i < n; ++i)
printf("%d \t\t %d\n", i, dist[i]);
}

// The main function that finds shortest distances from src
// to all other vertices using Bellman-Ford algorithm. The
// function also detects negative weight cycle
void BellmanFord(struct Graph *graph, int src)
{
int V = graph->V;
int E = graph->E;
int dist[V];

// Step 1: Initialize distances from src to all other
// vertices as INFINITE
for (int i = 0; i < V; i++)
dist[i] = INT_MAX;
dist[src] = 0;

// Step 2: Relax all edges |V| - 1 times. A simple
// shortest path from src to any other vertex can have
// at-most |V| - 1 edges
for (int i = 1; i <= V - 1; i++)
{
for (int j = 0; j < E; j++)
{
int u = graph->edge[j].src;
int v = graph->edge[j].dest;
int weight = graph->edge[j].weight;
if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
dist[v] = dist[u] + weight;
}
}

// Step 3: check for negative-weight cycles. The above
// step guarantees shortest distances if graph doesn't
// contain negative weight cycle. If we get a shorter
// path, then there is a cycle.
for (int i = 0; i < E; i++)
{
int u = graph->edge[i].src;
int v = graph->edge[i].dest;
int weight = graph->edge[i].weight;
if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
{
printf("Graph contains negative weight cycle");
return; // If negative cycle is detected, simply
// return
}
}

printArr(dist, V);

return;
}

// Driver's code
int main()
{
/* Let us create the graph given in above example */
int V = 5; // Number of vertices in graph
int E = 8; // Number of edges in graph
struct Graph *graph = createGraph(V, E);

// add edge 0-1 (or A-B in above figure)
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[0].weight = -1;

// add edge 0-2 (or A-C in above figure)
graph->edge[1].src = 0;
graph->edge[1].dest = 2;
graph->edge[1].weight = 4;

// add edge 1-2 (or B-C in above figure)
graph->edge[2].src = 1;
graph->edge[2].dest = 2;
graph->edge[2].weight = 3;

// add edge 1-3 (or B-D in above figure)
graph->edge[3].src = 1;
graph->edge[3].dest = 3;
graph->edge[3].weight = 2;

// add edge 1-4 (or B-E in above figure)
graph->edge[4].src = 1;
graph->edge[4].dest = 4;
graph->edge[4].weight = 2;

// add edge 3-2 (or D-C in above figure)
graph->edge[5].src = 3;
graph->edge[5].dest = 2;
graph->edge[5].weight = 5;

// add edge 3-1 (or D-B in above figure)
graph->edge[6].src = 3;
graph->edge[6].dest = 1;
graph->edge[6].weight = 1;

// add edge 4-3 (or E-D in above figure)
graph->edge[7].src = 4;
graph->edge[7].dest = 3;
graph->edge[7].weight = -3;

// Function call
BellmanFord(graph, 0);

return 0;
}
150 changes: 150 additions & 0 deletions C++program/Koseraju.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/* Implementation of Kosaraju's Algorithm to find out the strongly connected
components (SCCs) in a graph. Author:Anirban166
*/

#include <iostream>
#include <stack>
#include <vector>

/**
* Iterative function/method to print graph:
* @param a adjacency list representation of the graph
* @param V number of vertices
* @return void
**/
void print(const std::vector<std::vector<int>> &a, int V)
{
for (int i = 0; i < V; i++)
{
if (!a[i].empty())
{
std::cout << "i=" << i << "-->";
}
for (int j : a[i])
{
std::cout << j << " ";
}
if (!a[i].empty())
{
std::cout << std::endl;
}
}
}

/**
* //Recursive function/method to push vertices into stack passed as parameter:
* @param v vertices
* @param st stack passed by reference
* @param vis array to keep track of visited nodes (boolean type)
* @param adj adjacency list representation of the graph
* @return void
**/
void push_vertex(int v, std::stack<int> *st, std::vector<bool> *vis,
const std::vector<std::vector<int>> &adj)
{
(*vis)[v] = true;
for (auto i = adj[v].begin(); i != adj[v].end(); i++)
{
if ((*vis)[*i] == false)
{
push_vertex(*i, st, vis, adj);
}
}
st->push(v);
}

/**
* //Recursive function/method to implement depth first traversal(dfs):
* @param v vertices
* @param vis array to keep track of visited nodes (boolean type)
* @param grev graph with reversed edges
* @return void
**/
void dfs(int v, std::vector<bool> *vis,
const std::vector<std::vector<int>> &grev)
{
(*vis)[v] = true;
// cout<<v<<" ";
for (auto i = grev[v].begin(); i != grev[v].end(); i++)
{
if ((*vis)[*i] == false)
{
dfs(*i, vis, grev);
}
}
}

// function/method to implement Kosaraju's Algorithm:
/**
* Info about the method
* @param V vertices in graph
* @param adj array of vectors that represent a graph (adjacency list/array)
* @return int ( 0, 1, 2..and so on, only unsigned values as either there can be
no SCCs i.e. none(0) or there will be x no. of SCCs (x>0)) i.e. it returns the
count of (number of) strongly connected components (SCCs) in the graph.
(variable 'count_scc' within function)
**/
int kosaraju(int V, const std::vector<std::vector<int>> &adj)
{
std::vector<bool> vis(V, false);
std::stack<int> st;
for (int v = 0; v < V; v++)
{
if (vis[v] == false)
{
push_vertex(v, &st, &vis, adj);
}
}
// making new graph (grev) with reverse edges as in adj[]:
std::vector<std::vector<int>> grev(V);
for (int i = 0; i < V + 1; i++)
{
for (auto j = adj[i].begin(); j != adj[i].end(); j++)
{
grev[*j].push_back(i);
}
}
// cout<<"grev="<<endl; ->debug statement
// print(grev,V); ->debug statement
// reinitialise visited to 0
for (int i = 0; i < V; i++)
vis[i] = false;
int count_scc = 0;
while (!st.empty())
{
int t = st.top();
st.pop();
if (vis[t] == false)
{
dfs(t, &vis, grev);
count_scc++;
}
}
// cout<<"count_scc="<<count_scc<<endl; //in case you want to print here
// itself, uncomment & change return type of function to void.
return count_scc;
}

// All critical/corner cases have been taken care of.
// Input your required values: (not hardcoded)
int main()
{
int t = 0;
std::cin >> t;
while (t--)
{
int a = 0, b = 0; // a->number of nodes, b->directed edges.
std::cin >> a >> b;
int m = 0, n = 0;
std::vector<std::vector<int>> adj(a + 1);
for (int i = 0; i < b; i++) // take total b inputs of 2 vertices each
// required to form an edge.
{
std::cin >> m >> n; // take input m,n denoting edge from m->n.
adj[m].push_back(n);
}
// pass number of nodes and adjacency array as parameters to function:
std::cout << kosaraju(a, adj) << std::endl;
}
return 0;
}