Skip to content

Adding basic graph algos #437

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

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
103 changes: 103 additions & 0 deletions C++/Graph/Bellman-Ford/Source.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*****************************
* Author :: Prasanna Kumar *
*****************************/

/***********************************
* Unus pro omnibus, omnes pro uno *
***********************************/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
using namespace std::chrono;

#define __AcHiLlEs ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __AnAkLuSmOs freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define int long long
#define span(a) a.begin(), a.end()
#define sum(n) ((int)n * (int)(n + 1)) / 2
#define sumr(l, r) sum(r) - sum(l)

const int inf = (int)1e18;

struct edge {
int a, b, w;
};

template<typename t>
class Graph {
public:
vector<vector<pair<t, t>>> adj; // Adjecency List of Graph
vector<vector<t>> dist; // Distance matrix (Distance of each node to each other node)
vector<edge> edgeList;
vector<bool> vis; // Bool array to check if shortest paths from this node is already calulated or not.
t n, m; // n = number of nodes, m = number of edges

Graph(t n, t m) : n(n), m(m) { // Constructor to initialize graph with n nodes and m edges
adj.resize(n + 1); // Initialize adjecenct list for node numbers 1 to n
dist.resize(n + 1); // Initialize Distance matrix for node numbers 1 to n
vis.resize(n + 1, 0); // Initialize vis array with 0 marking all nodes unvisited
}

void join(t x, t y, t d) { // Join two nodes with an edge of weight d
adj[x].push_back({y, d});
edgeList.push_back({x, y, d});
}

int BellmanFord (t s, t e) {
if (dist[s].size()) return dist[s][e];

dist[s].assign(n + 1, inf);
dist[s][s] = 0;
queue<int> q;
for (int i = 0; i < n; i++) {
while (!q.empty()) q.pop();
for (auto &j: edgeList) {
if (dist[s][j.a] < inf)
if (dist[s][j.b] > dist[s][j.a] + j.w)
dist[s][j.b] = max(-inf, dist[s][j.a] + j.w), q.push(j.b);
}
if (q.empty()) break;
}
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = 1;
dist[s][u] = LLONG_MIN;
for (auto &v: adj[u]) if (!vis[v.first]) q.push(v.first), vis[v.first] = 1;
}
return dist[s][e];
}
};

void solve() {
int n, m;
cin >> n >> m;
Graph<int> gph(n, m); // declare graph
for (int i = 0; i < m; i++) {
int x, y, d;
cin >> x >> y >> d;
gph.join(x, y, d); // add edges
}
int s, e;
int res = gph.BellmanFord(1, n);
cout << (res == LLONG_MIN ? -1 : res) << "\n";
}

signed main() {
// auto start = high_resolution_clock::now();
#ifndef ONLINE_JUDGE
__AnAkLuSmOs
#endif

__AcHiLlEs

int t(1);
// cin >> t;
for (int i = 1; i <= t; /*cout << "Case " << i << ": ",*/ solve(), i++);
// auto stop = high_resolution_clock::now();
// double duration = duration_cast<microseconds>(stop - start).count();
// cout << fixed << setprecision(4) << duration / 1000000 << "\n";
return 0;
}
73 changes: 73 additions & 0 deletions C++/Graph/Breadth First Search/BFS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Breadth First Search

/*****************************
* Author :: Prasanna Kumar *
*****************************/

/***********************************
* Unus pro omnibus, omnes pro uno *
***********************************/
#include<bits/stdc++.h>
using namespace std;

#define __AcHiLlEs ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __AnAkLuSmOs freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define int long long


template<typename t>
class Graph {
public:
vector<vector<pair<t, t>>> adj; // Adjecency List of Graph
vector<vector<t>> dist; // Distance matrix (Distance of each node to each other node)
vector<bool> vis; // Bool array to check visited nodes.
t n, m; // n = number of nodes, m = number of edges

Graph(t n, t m) : n(n), m(m) { // Constructor to initialize graph with n nodes and m edges
adj.resize(n + 1); // Initialize adjecenct list for node numbers 1 to n
dist.resize(n + 1); // Initialize Distance matrix for node numbers 1 to n
vis.resize(n + 1, 0); // Initialize vis array with 0 marking all nodes unvisited
}

void join(t x, t y, t d) { // Join two nodes with an edge of weight d
adj[x].push_back({y, d});
adj[y].push_back({x, d});
}

void BFS (int s = 1) {
queue<t> q; // queue for bfs
q.push(s); // insert start node
vis[s] = 1; // mark visited
while (!q.empty()) {
t u = q.front(); // store the top element
q.pop(); // pop the element
cout << u << " "; // print the element
for (auto &v: adj[u]) if (!vis[v.first]) q.push(v.first), vis[v.first] = 1; // insert the unvisited adjacent nodes
}
}
};

void solve() {
int n, m;
cin >> n >> m;
Graph<int> gph(n, m); // declare graph
for (int i = 0; i < m; i++) {
int x, y, d;
cin >> x >> y >> d;
gph.join(x, y, d); // add edges
}
gph.BFS();
}

signed main() {
#ifndef ONLINE_JUDGE
__AnAkLuSmOs
#endif

__AcHiLlEs

int t(1);
// cin >> t;
for (int i = 1; i <= t; /*cout << "Case " << i << ": ",*/ solve(), i++);
return 0;
}
83 changes: 83 additions & 0 deletions C++/Graph/Depth First Search/DFS.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Depth First Search

/*****************************
* Author :: Prasanna Kumar *
*****************************/

/***********************************
* Unus pro omnibus, omnes pro uno *
***********************************/
#include<bits/stdc++.h>
using namespace std;

#define __AcHiLlEs ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __AnAkLuSmOs freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define int long long


template<typename t>
class Graph {
public:
vector<vector<pair<t, t>>> adj; // Adjecency List of Graph
vector<vector<t>> dist; // Distance matrix (Distance of each node to each other node)
vector<bool> vis; // Bool array to check visited nodes.
t n, m; // n = number of nodes, m = number of edges

Graph(t n, t m) : n(n), m(m) { // Constructor to initialize graph with n nodes and m edges
adj.resize(n + 1); // Initialize adjecenct list for node numbers 1 to n
dist.resize(n + 1); // Initialize Distance matrix for node numbers 1 to n
vis.resize(n + 1, 0); // Initialize vis array with 0 marking all nodes unvisited
}

void join(t x, t y, t d) { // Join two nodes with an edge of weight d
adj[x].push_back({y, d});
adj[y].push_back({x, d});
}

void DFSIter (int s = 1) {
stack<t> q; // stack for dfs
q.push(s); // insert start node
vis[s] = 1; // mark visited
while (!q.empty()) {
t u = q.top(); // store the top element
q.pop(); // pop the element
cout << u << " "; // print the element
for (auto &v: adj[u]) if (!vis[v.first]) q.push(v.first), vis[v.first] = 1; // insert the unvisited adjacent nodes
}
}

void DFSRecur (int s = 1) { // Use recursion for implicit stack
cout << s << " ";
vis[s] = 1; // mark visited
for (auto &v: adj[s]) if (!vis[v.first])
DFSRecur(v.first); // insert the unvisited adjacent nodes
}
};

void solve() {
int n, m;
cin >> n >> m;
Graph<int> gph(n, m); // declare graph
for (int i = 0; i < m; i++) {
int x, y, d;
cin >> x >> y >> d;
gph.join(x, y, d); // add edges
}
gph.DFSIter();
cout << "\n";
gph.vis.assign(n + 1, 0);
gph.DFSRecur();
}

signed main() {
#ifndef ONLINE_JUDGE
__AnAkLuSmOs
#endif

__AcHiLlEs

int t(1);
// cin >> t;
for (int i = 1; i <= t; /*cout << "Case " << i << ": ",*/ solve(), i++);
return 0;
}
89 changes: 89 additions & 0 deletions C++/Graph/Dijkstra/Dijkstra.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Dijkstra's Algorithm - Single Source Shortest Path

/*****************************
* Author :: Prasanna Kumar *
*****************************/

/***********************************
* Unus pro omnibus, omnes pro uno *
***********************************/
#include<bits/stdc++.h>
using namespace std;

#define __AcHiLlEs ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define __AnAkLuSmOs freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define int long long


// Class for graph
template<typename t>
class Graph {
public:
vector<vector<pair<t, t>>> adj; // Adjecency List of Graph
vector<vector<t>> dist; // Distance matrix (Distance of each node to each other node)
vector<bool> vis; // Bool array to check if shortest paths from this node is already calulated or not.
t n, m; // n = number of nodes, m = number of edges

Graph(t n, t m) : n(n), m(m) { // Constructor to initialize graph with n nodes and m edges
adj.resize(n + 1); // Initialize adjecenct list for node numbers 1 to n
dist.resize(n + 1); // Initialize Distance matrix for node numbers 1 to n
vis.resize(n + 1, 0); // Initialize vis array with 0 marking all nodes unvisited
}

void join(t x, t y, t d) { // Join two nodes with an edge of weight d
adj[x].push_back({y, d});
adj[y].push_back({x, d});
}

int dijkstra(t s, t e) {
if (vis[s]) return dist[s][e]; // If all shortest paths from s are already computed return value
vis[s] = 1; // Mark node visited
dist[s].resize(n + 1, INT_MAX); // Initialize dist from s to all nodes with max value
dist[s][s] = 0; // Make dist from source to itself 0

priority_queue<pair<t, t>> q; // initialize priority queue to make heap (I will be using negetive values for making minheap rather than making actual min heap)
q.push({0, s}); // Insert source node with it's distance

while (!q.empty()) { // Run the while loop while queue is not empty
auto p = q.top(); // Save the minimum distance node pair in p
q.pop(); // Pop the queue
t u = p.second; // The node number
if (-p.first != dist[s][u]) continue; // If the node is already computed and hence it's distance is updated therefore continue.
for (auto &i: adj[u]) { // Run loop in adjecency list of the obtained node and relax all possible node distances
t T = i.first; // node number
t d = i.second; // node distance
if (dist[s][T] > dist[s][u] + d) { // If distance is modifiable
dist[s][T] = dist[s][u] + d; // update distance
q.push({-dist[s][T], T}); // insert in queue (negetive value to make it act like min-heap)
}
}
}
return dist[s][e]; // when loop is over return the distance computed
}
};

void solve() {
int n, m;
cin >> n >> m;
Graph<int> gph(n, m); // declare graph
for (int i = 0; i < m; i++) {
int x, y, d;
cin >> x >> y >> d;
gph.join(x, y, d); // add edges
}
for (int i = 0; i < n; i++)
cout << i << " " << gph.dijkstra(1, i + 1) << "\n";
}

signed main() {
#ifndef ONLINE_JUDGE
__AnAkLuSmOs
#endif

__AcHiLlEs

int t(1);
// cin >> t;
for (int i = 1; i <= t; /*cout << "Case " << i << ": ",*/ solve(), i++);
return 0;
}
Loading