mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-04-05 03:29:46 +08:00
Major rework to improve code quality and add automation checks (#805)
* delete secant method - it is identical to regula falsi * document + improvize root finding algorithms * attempt to document gaussian elimination * added file brief * commented doxygen-mainpage, added files-list link * corrected files list link path * files-list link correction - this time works :) * document successive approximations * cleaner equation * updating DIRECTORY.md * documented kmp string search * document brute force string search * document rabin-karp string search * fixed mainpage readme * doxygen v1.8.18 will suppress out the #minipage in the markdown * cpplint correction for header guard style * github action to auto format source code per cpplint standard * updated setting to add 1 space before `private` and `public` keywords * auto rename files and auto format code * added missing "run" for step * corrected asignmemt operation * fixed trim and assign syntax * added git move for renaming bad filenames * added missing pipe for trim * added missing space * use old and new fnames * store old fname using echo * move files only if there is a change in filename * put old filenames in quotes * use double quote for old filename * escape double quotes * remove old_fname * try escape characters and echo" * add file-type to find * cleanup echo * ensure all trim variables are also in quotes * try escape -quote again * remove second escpe quote * use single quote for first check * use carets instead of quotes * put variables in brackets * remove -e from echo * add debug echos * try print0 flag * find command with while instead of for-loop * find command using IFS instead * 🎉 IFS fix worked - escaped quotes for git mv * protetc each word in git mv .. * filename exists in lower cases - renamed * 🎉 git push enabled * updating DIRECTORY.md * git pull & then push * formatting filenamesd7af6fdc8c* formatting source-code ford7af6fdc8c* remove allman break before braces * updating DIRECTORY.md * added missing comma lost in previous commit * orchestrate all workflows * fix yml indentation * force push format changes, add title to DIRECTORY.md * pull before proceeding * reorganize pull commands * use master branches for actions * rename .cc files to .cpp * added class destructor to clean up dynamic memory allocation * rename to awesome workflow * commented whole repo cpplint - added modified files lint check * removed need for cpplint * attempt to use actions/checkout@master * temporary: no dependency on cpplint * formatting filenames153fb7b8a5* formatting source-code for153fb7b8a5* updating DIRECTORY.md * fix diff filename * added comments to the code * added test case * formatting source-code fora850308fba* updating DIRECTORY.md * added machine learning folder * added adaline algorithm * updating DIRECTORY.md * fixed issue [LWG2192](https://cplusplus.github.io/LWG/issue2192) for std::abs on MacOS * add cmath for same bug: [LWG2192](https://cplusplus.github.io/LWG/issue2192) for std::abs on MacOS * formatting source-code forf8925e4822* use STL's inner_product * formatting source-code forf94a330594* added range comments * define activation function * use equal initial weights * change test2 function to predict * activation function not friend * previous commit correction * added option for predict function to return value before applying activation function as optional argument * added test case to classify points lying within a sphere * improve documentation for adaline * formatting source-code for15ec4c3aba* added cmake to geometry folder * added algorithm include for std::max * add namespace - machine_learning * add namespace - statistics * add namespace - sorting * added sorting algos to namespace sorting * added namespace string_search * formatting source-code forfd69530515* added documentation to string_search namespace * feat: Add BFS and DFS algorithms to check for cycle in a directed graph * Remove const references for input of simple types Reason: overhead on access * fix bad code sorry for force push * Use pointer instead of the non-const reference because apparently google says so. * Remove a useless and possibly bad Graph constuctor overload * Explicitely specify type of vector during graph instantiation * updating DIRECTORY.md * find openMP before adding subdirectories * added kohonen self organizing map * updating DIRECTORY.md * remove older files and folders from gh-pages before adding new files * remove chronos library due to inacceptability by cpplint * use c++ specific static_cast instead * initialize radom number generator * updated image links with those from CPP repository * rename computer.... folder to numerical methods * added durand kerner method for root computation for arbitrarily large polynomials * fixed additional comma * fix cpplint errors * updating DIRECTORY.md * convert to function module * update documentation * move openmp to main loop * added two test cases * use INT16_MAX * remove return statement from omp-for loop and use "break" * run tests when no input is provided and skip tests when input polynomial is provided * while loop cannot have break - replaced with continue and check is present in the main while condition * (1) break while loop (2) skip runs on break_loop instead of hard-break * add documentation images * use long double for errors and tolerance checks * make iterator variable i local to threads * add critical secions to omp threads * bugfix: move file writing outside of the parallel loop othersie, there is no gurantee of the order of roots written to file * rename folder to data_structures * updating DIRECTORY.md * fix ambiguous symbol `size` * add data_structures to cmake * docs: enable tree view, add timestamp in footer, try clang assistaed parsing * doxygen - open links in external window * remove invalid parameter from function docs * use HTML5 img tag to resize images * move file to proper folder * fix documentations and cpplint * formatting source-code foraacaf9828c* updating DIRECTORY.md * cpplint: add braces for multiple statement if * add explicit link to badges * remove duplicate line Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * remove namespace indentation * remove file associations in settings * add author name * enable cmake in subfolders of data_structures * create and link object file * cpp lint fixes and instantiate template classes * cpp lint fixes and instantiate template classes Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * cpplint - ignore `build/include` Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * disable redundant gcc compilation in cpplint workflow Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * template header files contain function codes as well and removed redundant subfolders Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updating DIRECTORY.md * remove semicolons after functions in a class Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * cpplint header guard style Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * remove semilon Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * added LU decomposition algorithm Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * added QR decomposition algorithm Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * use QR decomposition to find eigen values Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updating DIRECTORY.md * use std::rand for thread safety Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * move srand to main() Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * cpplint braces correction Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updated eigen value documentation Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * fix matrix shift doc Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * rename CONTRIBUTION.md to CONTRIBUTING.md #836 * remove 'sort alphabetical order' check * added documentation check * remove extra paranthesis * added gitpod * added gitpod link from README * attempt to add vscode gitpod extensions * update gitpod extensions * add gitpod extensions cmake-tools and git-graph * remove gitpod init and add commands * use init to one time install doxygen, graphviz, cpplint * use gitpod dockerfile * add ninja build system to docker * remove configure task * add github prebuild specs to gitpod * disable gitpod addcommit * update documentation for kohonen_som * added ode solve using forward euler method * added mid-point euler ode solver * fixed itegration step equation * added semi-implicit euler ODE solver * updating DIRECTORY.md * fix cpplint issues - lines 117 and 124 * added documentation to ode group * corrected semi-implicit euler function * updated docs and test cases better structure * replace `free` with `delete` operator * formatting source-code forf55ab50cf2* updating DIRECTORY.md * main function must return * added machine learning group * added kohonen som topology algorithm * fix graph image path * updating DIRECTORY.md * fix braces * use snprintf instead of sprintf * use static_cast * hardcode character buffer size * fix machine learning groups in documentation * fix missing namespace function * replace kvedala fork references to TheAlgorithms * fix bug in counting_sort Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Anmol3299 <mittalanmol22@gmail.com>
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class graph
|
||||
{
|
||||
int v;
|
||||
list<int> *adj;
|
||||
|
||||
public:
|
||||
graph(int v);
|
||||
void addedge(int src, int dest);
|
||||
void printgraph();
|
||||
void bfs(int s);
|
||||
};
|
||||
graph::graph(int v)
|
||||
{
|
||||
this->v = v;
|
||||
this->adj = new list<int>[v];
|
||||
}
|
||||
void graph::addedge(int src, int dest)
|
||||
{
|
||||
src--;
|
||||
dest--;
|
||||
adj[src].push_back(dest);
|
||||
//adj[dest].push_back(src);
|
||||
}
|
||||
void graph::printgraph()
|
||||
{
|
||||
for (int i = 0; i < this->v; i++)
|
||||
{
|
||||
cout << "Adjacency list of vertex " << i + 1 << " is \n";
|
||||
list<int>::iterator it;
|
||||
for (it = adj[i].begin(); it != adj[i].end(); ++it)
|
||||
{
|
||||
cout << *it + 1 << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
void graph::bfs(int s)
|
||||
{
|
||||
bool *visited = new bool[this->v + 1];
|
||||
memset(visited, false, sizeof(bool) * (this->v + 1));
|
||||
visited[s] = true;
|
||||
list<int> q;
|
||||
q.push_back(s);
|
||||
list<int>::iterator it;
|
||||
while (!q.empty())
|
||||
{
|
||||
int u = q.front();
|
||||
cout << u << " ";
|
||||
q.pop_front();
|
||||
for (it = adj[u].begin(); it != adj[u].end(); ++it)
|
||||
{
|
||||
if (visited[*it] == false)
|
||||
{
|
||||
visited[*it] = true;
|
||||
q.push_back(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
graph g(4);
|
||||
g.addedge(1, 2);
|
||||
g.addedge(2, 3);
|
||||
g.addedge(3, 4);
|
||||
g.addedge(1, 4);
|
||||
g.addedge(1, 3);
|
||||
//g.printgraph();
|
||||
g.bfs(2);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int v = 4;
|
||||
void DFSUtil_(int graph[4][4], bool visited[], int s)
|
||||
{
|
||||
visited[s] = true;
|
||||
cout << s << " ";
|
||||
for (int i = 0; i < v; i++)
|
||||
{
|
||||
if (graph[s][i] == 1 && visited[i] == false)
|
||||
{
|
||||
DFSUtil_(graph, visited, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DFS_(int graph[4][4], int s)
|
||||
{
|
||||
bool visited[v];
|
||||
memset(visited, 0, sizeof(visited));
|
||||
DFSUtil_(graph, visited, s);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int graph[4][4] = {{0, 1, 1, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}};
|
||||
cout << "DFS: ";
|
||||
DFS_(graph, 2);
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
#include <iostream>
|
||||
//#include <boost/multiprecision/cpp_int.hpp>
|
||||
//using namespace boost::multiprecision;
|
||||
const int mx = 1e6 + 5;
|
||||
const long int inf = 2e9;
|
||||
typedef long long ll;
|
||||
#define rep(i, n) for (i = 0; i < n; i++)
|
||||
#define repp(i, a, b) for (i = a; i <= b; i++)
|
||||
#define pii pair<int, int>
|
||||
#define vpii vector<pii>
|
||||
#define vi vector<int>
|
||||
#define vll vector<ll>
|
||||
#define r(x) scanf("%d", &x)
|
||||
#define rs(s) scanf("%s", s)
|
||||
#define gc getchar_unlocked
|
||||
#define pc putchar_unlocked
|
||||
#define mp make_pair
|
||||
#define pb push_back
|
||||
#define lb lower_bound
|
||||
#define ub upper_bound
|
||||
#define endl "\n"
|
||||
#define fast \
|
||||
ios_base::sync_with_stdio(false); \
|
||||
cin.tie(NULL); \
|
||||
cout.tie(NULL);
|
||||
using namespace std;
|
||||
void in(int &x)
|
||||
{
|
||||
register int c = gc();
|
||||
x = 0;
|
||||
int neg = 0;
|
||||
for (; ((c < 48 || c > 57) && c != '-'); c = gc())
|
||||
;
|
||||
if (c == '-')
|
||||
{
|
||||
neg = 1;
|
||||
c = gc();
|
||||
}
|
||||
for (; c > 47 && c < 58; c = gc())
|
||||
{
|
||||
x = (x << 1) + (x << 3) + c - 48;
|
||||
}
|
||||
if (neg)
|
||||
x = -x;
|
||||
}
|
||||
void out(int n)
|
||||
{
|
||||
int N = n, rev, count = 0;
|
||||
rev = N;
|
||||
if (N == 0)
|
||||
{
|
||||
pc('0');
|
||||
return;
|
||||
}
|
||||
while ((rev % 10) == 0)
|
||||
{
|
||||
count++;
|
||||
rev /= 10;
|
||||
}
|
||||
rev = 0;
|
||||
while (N != 0)
|
||||
{
|
||||
rev = (rev << 3) + (rev << 1) + N % 10;
|
||||
N /= 10;
|
||||
}
|
||||
while (rev != 0)
|
||||
{
|
||||
pc(rev % 10 + '0');
|
||||
rev /= 10;
|
||||
}
|
||||
while (count--)
|
||||
pc('0');
|
||||
}
|
||||
ll parent[mx], arr[mx], node, edge;
|
||||
vector<pair<ll, pair<ll, ll>>> v;
|
||||
void initial()
|
||||
{
|
||||
int i;
|
||||
rep(i, node + edge)
|
||||
parent[i] = i;
|
||||
}
|
||||
int root(int i)
|
||||
{
|
||||
while (parent[i] != i)
|
||||
{
|
||||
parent[i] = parent[parent[i]];
|
||||
i = parent[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
void join(int x, int y)
|
||||
{
|
||||
int root_x = root(x); //Disjoint set union by rank
|
||||
int root_y = root(y);
|
||||
parent[root_x] = root_y;
|
||||
}
|
||||
ll kruskal()
|
||||
{
|
||||
ll mincost = 0, i, x, y;
|
||||
rep(i, edge)
|
||||
{
|
||||
x = v[i].second.first;
|
||||
y = v[i].second.second;
|
||||
if (root(x) != root(y))
|
||||
{
|
||||
mincost += v[i].first;
|
||||
join(x, y);
|
||||
}
|
||||
}
|
||||
return mincost;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
fast;
|
||||
while (1)
|
||||
{
|
||||
int i, j, from, to, cost, totalcost = 0;
|
||||
cin >> node >> edge; //Enter the nodes and edges
|
||||
if (node == 0 && edge == 0)
|
||||
break; //Enter 0 0 to break out
|
||||
initial(); //Initialise the parent array
|
||||
rep(i, edge)
|
||||
{
|
||||
cin >> from >> to >> cost;
|
||||
v.pb(mp(cost, mp(from, to)));
|
||||
totalcost += cost;
|
||||
}
|
||||
sort(v.begin(), v.end());
|
||||
// rep(i,v.size())
|
||||
// cout<<v[i].first<<" ";
|
||||
cout << kruskal() << endl;
|
||||
v.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
int n, m; // For number of Vertices (V) and number of edges (E)
|
||||
vector<vector<int>> G;
|
||||
vector<bool> visited;
|
||||
vector<int> ans;
|
||||
|
||||
void dfs(int v)
|
||||
{
|
||||
visited[v] = true;
|
||||
for (int u : G[v])
|
||||
{
|
||||
if (!visited[u])
|
||||
dfs(u);
|
||||
}
|
||||
ans.push_back(v);
|
||||
}
|
||||
|
||||
void topological_sort()
|
||||
{
|
||||
visited.assign(n, false);
|
||||
ans.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (!visited[i])
|
||||
dfs(i);
|
||||
}
|
||||
reverse(ans.begin(), ans.end());
|
||||
}
|
||||
int main()
|
||||
{
|
||||
cout << "Enter the number of vertices and the number of directed edges\n";
|
||||
cin >> n >> m;
|
||||
int x, y;
|
||||
G.resize(n, vector<int>());
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
cin >> x >> y;
|
||||
x--, y--; // to convert 1-indexed to 0-indexed
|
||||
G[x].push_back(y);
|
||||
}
|
||||
topological_sort();
|
||||
cout << "Topological Order : \n";
|
||||
for (int v : ans)
|
||||
{
|
||||
cout << v + 1 << ' '; // converting zero based indexing back to one based.
|
||||
}
|
||||
cout << '\n';
|
||||
return 0;
|
||||
}
|
||||
62
graph/bfs.cpp
Normal file
62
graph/bfs.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class graph {
|
||||
int v;
|
||||
list<int> *adj;
|
||||
|
||||
public:
|
||||
graph(int v);
|
||||
void addedge(int src, int dest);
|
||||
void printgraph();
|
||||
void bfs(int s);
|
||||
};
|
||||
graph::graph(int v) {
|
||||
this->v = v;
|
||||
this->adj = new list<int>[v];
|
||||
}
|
||||
void graph::addedge(int src, int dest) {
|
||||
src--;
|
||||
dest--;
|
||||
adj[src].push_back(dest);
|
||||
// adj[dest].push_back(src);
|
||||
}
|
||||
void graph::printgraph() {
|
||||
for (int i = 0; i < this->v; i++) {
|
||||
cout << "Adjacency list of vertex " << i + 1 << " is \n";
|
||||
list<int>::iterator it;
|
||||
for (it = adj[i].begin(); it != adj[i].end(); ++it) {
|
||||
cout << *it + 1 << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
void graph::bfs(int s) {
|
||||
bool *visited = new bool[this->v + 1];
|
||||
memset(visited, false, sizeof(bool) * (this->v + 1));
|
||||
visited[s] = true;
|
||||
list<int> q;
|
||||
q.push_back(s);
|
||||
list<int>::iterator it;
|
||||
while (!q.empty()) {
|
||||
int u = q.front();
|
||||
cout << u << " ";
|
||||
q.pop_front();
|
||||
for (it = adj[u].begin(); it != adj[u].end(); ++it) {
|
||||
if (visited[*it] == false) {
|
||||
visited[*it] = true;
|
||||
q.push_back(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main() {
|
||||
graph g(4);
|
||||
g.addedge(1, 2);
|
||||
g.addedge(2, 3);
|
||||
g.addedge(3, 4);
|
||||
g.addedge(1, 4);
|
||||
g.addedge(1, 3);
|
||||
// g.printgraph();
|
||||
g.bfs(2);
|
||||
return 0;
|
||||
}
|
||||
@@ -4,27 +4,27 @@
|
||||
* Last Modified Date: May 24, 2020
|
||||
*
|
||||
*/
|
||||
#include <vector> // for std::vector
|
||||
#include <algorithm> // for min & max
|
||||
#include <iostream> // for cout
|
||||
using std::vector;
|
||||
#include <iostream> // for cout
|
||||
#include <vector> // for std::vector
|
||||
using std::cout;
|
||||
using std::min;
|
||||
using std::vector;
|
||||
class Solution {
|
||||
vector < vector < int > > graph;
|
||||
vector<int>in_time , out_time;
|
||||
vector<vector<int>> graph;
|
||||
vector<int> in_time, out_time;
|
||||
int timer;
|
||||
vector < vector < int > > bridge;
|
||||
vector<bool>visited;
|
||||
void dfs(int current_node , int parent) {
|
||||
vector<vector<int>> bridge;
|
||||
vector<bool> visited;
|
||||
void dfs(int current_node, int parent) {
|
||||
visited.at(current_node) = true;
|
||||
in_time[current_node] = out_time[current_node] = timer++;
|
||||
for ( auto&itr : graph[current_node] ) {
|
||||
for (auto& itr : graph[current_node]) {
|
||||
if (itr == parent) {
|
||||
continue;
|
||||
}
|
||||
if (!visited[itr]) {
|
||||
dfs(itr , current_node);
|
||||
dfs(itr, current_node);
|
||||
if (out_time[itr] > in_time[current_node]) {
|
||||
bridge.push_back({itr, current_node});
|
||||
}
|
||||
@@ -34,14 +34,14 @@ class Solution {
|
||||
}
|
||||
|
||||
public:
|
||||
vector <vector <int> > search_bridges(int n,
|
||||
const vector<vector<int>>& connections) {
|
||||
vector<vector<int>> search_bridges(int n,
|
||||
const vector<vector<int>>& connections) {
|
||||
timer = 0;
|
||||
graph.resize(n);
|
||||
in_time.assign(n, 0);
|
||||
visited.assign(n, false);
|
||||
out_time.assign(n, 0);
|
||||
for (auto&itr : connections) {
|
||||
for (auto& itr : connections) {
|
||||
graph.at(itr[0]).push_back(itr[1]);
|
||||
graph.at(itr[1]).push_back(itr[0]);
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class Solution {
|
||||
int main(void) {
|
||||
Solution s1;
|
||||
int number_of_node = 5;
|
||||
vector< vector <int> >node;
|
||||
vector<vector<int>> node;
|
||||
node.push_back({0, 1});
|
||||
node.push_back({1, 3});
|
||||
node.push_back({1, 2});
|
||||
@@ -66,13 +66,13 @@ int main(void) {
|
||||
* 3 4
|
||||
*
|
||||
* In this graph there are 4 bridges [0,2] , [2,4] , [3,5] , [1,2]
|
||||
*
|
||||
*
|
||||
* I assumed that the graph is bi-directional and connected.
|
||||
*
|
||||
*/
|
||||
vector< vector <int> > bridges = s1.search_bridges(number_of_node , node);
|
||||
vector<vector<int>> bridges = s1.search_bridges(number_of_node, node);
|
||||
cout << bridges.size() << " bridges found!\n";
|
||||
for (auto&itr : bridges) {
|
||||
for (auto& itr : bridges) {
|
||||
cout << itr[0] << " --> " << itr[1] << '\n';
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -8,48 +8,47 @@ class graph {
|
||||
vector<vector<int>> adj;
|
||||
int connected_components;
|
||||
void depth_first_search();
|
||||
void explore(int, vector<bool>&);
|
||||
void explore(int, vector<bool> &);
|
||||
|
||||
public:
|
||||
explicit graph(int n): adj(n, vector<int>()) {
|
||||
connected_components = 0;
|
||||
}
|
||||
explicit graph(int n) : adj(n, vector<int>()) { connected_components = 0; }
|
||||
void addEdge(int, int);
|
||||
int getConnectedComponents() {
|
||||
depth_first_search();
|
||||
return connected_components;
|
||||
depth_first_search();
|
||||
return connected_components;
|
||||
}
|
||||
};
|
||||
|
||||
void graph::addEdge(int u, int v) {
|
||||
adj[u-1].push_back(v-1);
|
||||
adj[v-1].push_back(u-1);
|
||||
adj[u - 1].push_back(v - 1);
|
||||
adj[v - 1].push_back(u - 1);
|
||||
}
|
||||
|
||||
void graph::depth_first_search() {
|
||||
int n = adj.size();
|
||||
vector<bool> visited(n, false);
|
||||
int n = adj.size();
|
||||
vector<bool> visited(n, false);
|
||||
|
||||
for (int i = 0 ; i < n ; i++) {
|
||||
if (!visited[i]) {
|
||||
explore(i, visited);
|
||||
connected_components++;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (!visited[i]) {
|
||||
explore(i, visited);
|
||||
connected_components++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void graph::explore(int u, vector<bool> &visited) {
|
||||
visited[u] = true;
|
||||
for (auto v : adj[u]) {
|
||||
if (!visited[v]) {
|
||||
explore(v, visited);
|
||||
visited[u] = true;
|
||||
for (auto v : adj[u]) {
|
||||
if (!visited[v]) {
|
||||
explore(v, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
graph g(4);
|
||||
g.addEdge(1, 2);
|
||||
g.addEdge(3, 2);
|
||||
std::cout << g.getConnectedComponents();
|
||||
return 0;
|
||||
graph g(4);
|
||||
g.addEdge(1, 2);
|
||||
g.addEdge(3, 2);
|
||||
std::cout << g.getConnectedComponents();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
int N; // denotes number of nodes;
|
||||
std::vector<int> parent;
|
||||
@@ -31,8 +31,7 @@ void union_sets(int a, int b) { // To join 2 components to belong to one
|
||||
|
||||
int no_of_connected_components() { // To find total no of connected components
|
||||
std::set<int> temp; // temp set to count number of connected components
|
||||
for (int i = 1; i <= N; i++)
|
||||
temp.insert(find_set(i));
|
||||
for (int i = 1; i <= N; i++) temp.insert(find_set(i));
|
||||
return temp.size();
|
||||
}
|
||||
|
||||
|
||||
302
graph/cycle_check_directed_graph.cpp
Normal file
302
graph/cycle_check_directed_graph.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* Copyright 2020
|
||||
* @file cycle_check_directed graph.cpp
|
||||
*
|
||||
* @brief BFS and DFS algorithms to check for cycle in a directed graph.
|
||||
*
|
||||
* @author Anmol3299
|
||||
* contact: mittalanmol22@gmail.com
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream> // for std::cout
|
||||
#include <queue> // for std::queue
|
||||
#include <stdexcept> // for throwing errors
|
||||
#include <type_traits> // for std::remove_reference_t
|
||||
#include <unordered_map> // for std::unordered_map
|
||||
#include <utility> // for std::move
|
||||
#include <vector> // for std::vector
|
||||
|
||||
/**
|
||||
* Implementation of non-weighted directed edge of a graph.
|
||||
*
|
||||
* The source vertex of the edge is labelled "src" and destination vertex is
|
||||
* labelled "dest".
|
||||
*/
|
||||
struct Edge {
|
||||
unsigned int src;
|
||||
unsigned int dest;
|
||||
|
||||
Edge() = delete;
|
||||
~Edge() = default;
|
||||
Edge(Edge&&) = default;
|
||||
Edge& operator=(Edge&&) = default;
|
||||
Edge(Edge const&) = default;
|
||||
Edge& operator=(Edge const&) = default;
|
||||
|
||||
/** Set the source and destination of the vertex.
|
||||
*
|
||||
* @param source is the source vertex of the edge.
|
||||
* @param destination is the destination vertex of the edge.
|
||||
*/
|
||||
Edge(unsigned int source, unsigned int destination)
|
||||
: src(source), dest(destination) {}
|
||||
};
|
||||
|
||||
using AdjList = std::unordered_map<unsigned int, std::vector<unsigned int>>;
|
||||
|
||||
/**
|
||||
* Implementation of graph class.
|
||||
*
|
||||
* The graph will be represented using Adjacency List representation.
|
||||
* This class contains 2 data members "m_vertices" & "m_adjList" used to
|
||||
* represent the number of vertices and adjacency list of the graph
|
||||
* respectively. The vertices are labelled 0 - (m_vertices - 1).
|
||||
*/
|
||||
class Graph {
|
||||
public:
|
||||
Graph() : m_vertices(0), m_adjList({}) {}
|
||||
~Graph() = default;
|
||||
Graph(Graph&&) = default;
|
||||
Graph& operator=(Graph&&) = default;
|
||||
Graph(Graph const&) = default;
|
||||
Graph& operator=(Graph const&) = default;
|
||||
|
||||
/** Create a graph from vertices and adjacency list.
|
||||
*
|
||||
* @param vertices specify the number of vertices the graph would contain.
|
||||
* @param adjList is the adjacency list representation of graph.
|
||||
*/
|
||||
Graph(unsigned int vertices, AdjList const& adjList)
|
||||
: m_vertices(vertices), m_adjList(adjList) {}
|
||||
|
||||
/** Create a graph from vertices and adjacency list.
|
||||
*
|
||||
* @param vertices specify the number of vertices the graph would contain.
|
||||
* @param adjList is the adjacency list representation of graph.
|
||||
*/
|
||||
Graph(unsigned int vertices, AdjList&& adjList)
|
||||
: m_vertices(std::move(vertices)), m_adjList(std::move(adjList)) {}
|
||||
|
||||
/** Create a graph from vertices and a set of edges.
|
||||
*
|
||||
* Adjacency list of the graph would be created from the set of edges. If
|
||||
* the source or destination of any edge has a value greater or equal to
|
||||
* number of vertices, then it would throw a range_error.
|
||||
*
|
||||
* @param vertices specify the number of vertices the graph would contain.
|
||||
* @param edges is a vector of edges.
|
||||
*/
|
||||
Graph(unsigned int vertices, std::vector<Edge> const& edges)
|
||||
: m_vertices(vertices) {
|
||||
for (auto const& edge : edges) {
|
||||
if (edge.src >= vertices || edge.dest >= vertices) {
|
||||
throw std::range_error(
|
||||
"Either src or dest of edge out of range");
|
||||
}
|
||||
m_adjList[edge.src].emplace_back(edge.dest);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a const reference of the adjacency list.
|
||||
*
|
||||
* @return const reference to the adjacency list
|
||||
*/
|
||||
std::remove_reference_t<AdjList> const& getAdjList() const {
|
||||
return m_adjList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of vertices in the graph.
|
||||
*/
|
||||
std::remove_reference_t<unsigned int> const& getVertices() const {
|
||||
return m_vertices;
|
||||
}
|
||||
|
||||
/** Add vertices in the graph.
|
||||
*
|
||||
* @param num is the number of vertices to be added. It adds 1 vertex by
|
||||
* default.
|
||||
*
|
||||
*/
|
||||
void addVertices(unsigned int num = 1) { m_vertices += num; }
|
||||
|
||||
/** Add an edge in the graph.
|
||||
*
|
||||
* @param edge that needs to be added.
|
||||
*/
|
||||
void addEdge(Edge const& edge) {
|
||||
if (edge.src >= m_vertices || edge.dest >= m_vertices) {
|
||||
throw std::range_error("Either src or dest of edge out of range");
|
||||
}
|
||||
m_adjList[edge.src].emplace_back(edge.dest);
|
||||
}
|
||||
|
||||
/** Add an Edge in the graph
|
||||
*
|
||||
* @param source is source vertex of the edge.
|
||||
* @param destination is the destination vertex of the edge.
|
||||
*/
|
||||
void addEdge(unsigned int source, unsigned int destination) {
|
||||
if (source >= m_vertices || destination >= m_vertices) {
|
||||
throw std::range_error(
|
||||
"Either source or destination of edge out of range");
|
||||
}
|
||||
m_adjList[source].emplace_back(destination);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int m_vertices;
|
||||
AdjList m_adjList;
|
||||
};
|
||||
|
||||
class CycleCheck {
|
||||
private:
|
||||
enum nodeStates : uint8_t { not_visited = 0, in_stack, visited };
|
||||
|
||||
/** Helper function of "isCyclicDFS".
|
||||
*
|
||||
* @param adjList is the adjacency list representation of some graph.
|
||||
* @param state is the state of the nodes of the graph.
|
||||
* @param node is the node being evaluated.
|
||||
*
|
||||
* @return true if graph has a cycle, else false.
|
||||
*/
|
||||
static bool isCyclicDFSHelper(AdjList const& adjList,
|
||||
std::vector<nodeStates>* state,
|
||||
unsigned int node) {
|
||||
// Add node "in_stack" state.
|
||||
(*state)[node] = in_stack;
|
||||
|
||||
// If the node has children, then recursively visit all children of the
|
||||
// node.
|
||||
if (auto const& it = adjList.find(node); it != adjList.end()) {
|
||||
for (auto child : it->second) {
|
||||
// If state of child node is "not_visited", evaluate that child
|
||||
// for presence of cycle.
|
||||
if (auto state_of_child = (*state)[child];
|
||||
state_of_child == not_visited) {
|
||||
if (isCyclicDFSHelper(adjList, state, child)) {
|
||||
return true;
|
||||
}
|
||||
} else if (state_of_child == in_stack) {
|
||||
// If child node was "in_stack", then that means that there
|
||||
// is a cycle in the graph. Return true for presence of the
|
||||
// cycle.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Current node has been evaluated for the presence of cycle and had no
|
||||
// cycle. Mark current node as "visited".
|
||||
(*state)[node] = visited;
|
||||
// Return that current node didn't result in any cycles.
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
/** Driver function to check if a graph has a cycle.
|
||||
*
|
||||
* This function uses DFS to check for cycle in the graph.
|
||||
*
|
||||
* @param graph which needs to be evaluated for the presence of cycle.
|
||||
* @return true if a cycle is detected, else false.
|
||||
*/
|
||||
static bool isCyclicDFS(Graph const& graph) {
|
||||
/** State of the node.
|
||||
*
|
||||
* It is a vector of "nodeStates" which represents the state node is in.
|
||||
* It can take only 3 values: "not_visited", "in_stack", and "visited".
|
||||
*
|
||||
* Initially, all nodes are in "not_visited" state.
|
||||
*/
|
||||
std::vector<nodeStates> state(graph.getVertices(), not_visited);
|
||||
|
||||
// Start visiting each node.
|
||||
for (auto node = 0; node < graph.getVertices(); node++) {
|
||||
// If a node is not visited, only then check for presence of cycle.
|
||||
// There is no need to check for presence of cycle for a visited
|
||||
// node as it has already been checked for presence of cycle.
|
||||
if (state[node] == not_visited) {
|
||||
// Check for cycle.
|
||||
if (isCyclicDFSHelper(graph.getAdjList(), &state, node)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All nodes have been safely traversed, that means there is no cycle in
|
||||
// the graph. Return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check if a graph has cycle or not.
|
||||
*
|
||||
* This function uses BFS to check if a graph is cyclic or not.
|
||||
*
|
||||
* @param graph which needs to be evaluated for the presence of cycle.
|
||||
* @return true if a cycle is detected, else false.
|
||||
*/
|
||||
static bool isCyclicBFS(Graph const& graph) {
|
||||
AdjList graphAjdList = graph.getAdjList();
|
||||
|
||||
std::vector<unsigned int> indegree(graph.getVertices(), 0);
|
||||
// Calculate the indegree i.e. the number of incident edges to the node.
|
||||
for (auto const& [parent, children] : graphAjdList) {
|
||||
for (auto const& child : children) {
|
||||
indegree[child]++;
|
||||
}
|
||||
}
|
||||
|
||||
std::queue<unsigned int> can_be_solved;
|
||||
for (auto node = 0; node < graph.getVertices(); node++) {
|
||||
// If a node doesn't have any input edges, then that node will
|
||||
// definately not result in a cycle and can be visited safely.
|
||||
if (!indegree[node]) {
|
||||
can_be_solved.emplace(node);
|
||||
}
|
||||
}
|
||||
|
||||
// Vertices that need to be traversed.
|
||||
auto remain = graph.getVertices();
|
||||
// While there are safe nodes that we can visit.
|
||||
while (!can_be_solved.empty()) {
|
||||
auto front = can_be_solved.front();
|
||||
// Visit the node.
|
||||
can_be_solved.pop();
|
||||
// Decrease number of nodes that need to be traversed.
|
||||
remain--;
|
||||
|
||||
// Visit all the children of the visited node.
|
||||
if (auto it = graphAjdList.find(front); it != graphAjdList.end()) {
|
||||
for (auto child : it->second) {
|
||||
// Check if we can visited the node safely.
|
||||
if (--indegree[child] == 0) {
|
||||
// if node can be visited safely, then add that node to
|
||||
// the visit queue.
|
||||
can_be_solved.emplace(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are still nodes that we can't visit, then it means that
|
||||
// there is a cycle and return true, else return false.
|
||||
return !(remain == 0);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Main function.
|
||||
*/
|
||||
int main() {
|
||||
// Instantiate the graph.
|
||||
Graph g(7, std::vector<Edge>{{0, 1}, {1, 2}, {2, 0}, {2, 5}, {3, 5}});
|
||||
// Check for cycle using BFS method.
|
||||
std::cout << CycleCheck::isCyclicBFS(g) << '\n';
|
||||
|
||||
// Check for cycle using DFS method.
|
||||
std::cout << CycleCheck::isCyclicDFS(g) << '\n';
|
||||
return 0;
|
||||
}
|
||||
26
graph/dfs.cpp
Normal file
26
graph/dfs.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int v = 4;
|
||||
void DFSUtil_(int graph[4][4], bool visited[], int s) {
|
||||
visited[s] = true;
|
||||
cout << s << " ";
|
||||
for (int i = 0; i < v; i++) {
|
||||
if (graph[s][i] == 1 && visited[i] == false) {
|
||||
DFSUtil_(graph, visited, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DFS_(int graph[4][4], int s) {
|
||||
bool visited[v];
|
||||
memset(visited, 0, sizeof(visited));
|
||||
DFSUtil_(graph, visited, s);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int graph[4][4] = {{0, 1, 1, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}, {0, 0, 0, 1}};
|
||||
cout << "DFS: ";
|
||||
DFS_(graph, 2);
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -11,8 +11,7 @@ using namespace std;
|
||||
|
||||
int checked[999] = {WHITE};
|
||||
|
||||
void dfs(const list<int> lista[], int start)
|
||||
{
|
||||
void dfs(const list<int> lista[], int start) {
|
||||
stack<int> stack;
|
||||
|
||||
int checked[999] = {WHITE};
|
||||
@@ -20,33 +19,28 @@ void dfs(const list<int> lista[], int start)
|
||||
stack.push(start);
|
||||
|
||||
checked[start] = GREY;
|
||||
while (!stack.empty())
|
||||
{
|
||||
while (!stack.empty()) {
|
||||
int act = stack.top();
|
||||
stack.pop();
|
||||
|
||||
if (checked[act] == GREY)
|
||||
{
|
||||
if (checked[act] == GREY) {
|
||||
cout << act << ' ';
|
||||
for (auto it = lista[act].begin(); it != lista[act].end(); ++it)
|
||||
{
|
||||
for (auto it = lista[act].begin(); it != lista[act].end(); ++it) {
|
||||
stack.push(*it);
|
||||
if (checked[*it] != BLACK)
|
||||
checked[*it] = GREY;
|
||||
}
|
||||
checked[act] = BLACK; //nodo controllato
|
||||
checked[act] = BLACK; // nodo controllato
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
int u, w;
|
||||
int n;
|
||||
cin >> n;
|
||||
list<int> lista[INF];
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
for (int i = 0; i < n; ++i) {
|
||||
cin >> u >> w;
|
||||
lista[u].push_back(w);
|
||||
}
|
||||
@@ -1,49 +1,46 @@
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
#define INF 10000010
|
||||
vector<pair<int, int>> graph[5 * 100001];
|
||||
int dis[5 * 100001];
|
||||
int dij(vector<pair<int, int>> *v, int s, int *dis)
|
||||
{
|
||||
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
|
||||
int dij(vector<pair<int, int>> *v, int s, int *dis) {
|
||||
priority_queue<pair<int, int>, vector<pair<int, int>>,
|
||||
greater<pair<int, int>>>
|
||||
pq;
|
||||
// source distance to zero.
|
||||
pq.push(make_pair(0, s));
|
||||
dis[s] = 0;
|
||||
int u;
|
||||
while (!pq.empty())
|
||||
{
|
||||
while (!pq.empty()) {
|
||||
u = (pq.top()).second;
|
||||
pq.pop();
|
||||
for (vector<pair<int, int>>::iterator it = v[u].begin(); it != v[u].end(); it++)
|
||||
{
|
||||
if (dis[u] + it->first < dis[it->second])
|
||||
{
|
||||
for (vector<pair<int, int>>::iterator it = v[u].begin();
|
||||
it != v[u].end(); it++) {
|
||||
if (dis[u] + it->first < dis[it->second]) {
|
||||
dis[it->second] = dis[u] + it->first;
|
||||
pq.push(make_pair(dis[it->second], it->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
int m, n, l, x, y, s;
|
||||
// n--> number of nodes , m --> number of edges
|
||||
cin >> n >> m;
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
for (int i = 0; i < m; i++) {
|
||||
// input edges.
|
||||
scanf("%d%d%d", &x, &y, &l);
|
||||
graph[x].push_back(make_pair(l, y));
|
||||
graph[y].push_back(make_pair(l, x)); // comment this line for directed graph
|
||||
graph[y].push_back(
|
||||
make_pair(l, x)); // comment this line for directed graph
|
||||
}
|
||||
// start node.
|
||||
scanf("%d", &s);
|
||||
// intialise all distances to infinity.
|
||||
for (int i = 1; i <= n; i++)
|
||||
dis[i] = INF;
|
||||
for (int i = 1; i <= n; i++) dis[i] = INF;
|
||||
dij(graph, s, dis);
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
@@ -1,134 +1,121 @@
|
||||
/* Implementation of Kosaraju's Algorithm to find out the strongly connected components (SCCs) in a graph.
|
||||
Author:Anirban166
|
||||
*/
|
||||
/* Implementation of Kosaraju's Algorithm to find out the strongly connected
|
||||
components (SCCs) in a graph. Author:Anirban166
|
||||
*/
|
||||
|
||||
#include<iostream>
|
||||
#include<vector>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Iterative function/method to print graph:
|
||||
* @param a[] : array of vectors (2D)
|
||||
* @param V : vertices
|
||||
* @return void
|
||||
**/
|
||||
void print(vector<int> a[],int V)
|
||||
{
|
||||
for(int i=0;i<V;i++)
|
||||
{
|
||||
if(!a[i].empty())
|
||||
cout<<"i="<<i<<"-->";
|
||||
for(int j=0;j<a[i].size();j++)
|
||||
cout<<a[i][j]<<" ";
|
||||
if(!a[i].empty())
|
||||
cout<<endl;
|
||||
* Iterative function/method to print graph:
|
||||
* @param a[] : array of vectors (2D)
|
||||
* @param V : vertices
|
||||
* @return void
|
||||
**/
|
||||
void print(vector<int> a[], int V) {
|
||||
for (int i = 0; i < V; i++) {
|
||||
if (!a[i].empty())
|
||||
cout << "i=" << i << "-->";
|
||||
for (int j = 0; j < a[i].size(); j++) cout << a[i][j] << " ";
|
||||
if (!a[i].empty())
|
||||
cout << 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[] : array of vectors to represent graph
|
||||
* @return void
|
||||
**/
|
||||
void push_vertex(int v,stack<int> &st,bool vis[],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);
|
||||
* //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[] : array of vectors to represent graph
|
||||
* @return void
|
||||
**/
|
||||
void push_vertex(int v, stack<int> &st, bool vis[], 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,bool vis[],vector<int> grev[])
|
||||
{
|
||||
vis[v]=true;
|
||||
* //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, bool vis[], 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);
|
||||
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:
|
||||
// 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)
|
||||
* @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, vector<int> adj[])
|
||||
{
|
||||
bool vis[V]={};
|
||||
int kosaraju(int V, vector<int> adj[]) {
|
||||
bool vis[V] = {};
|
||||
stack<int> st;
|
||||
for(int v=0;v<V;v++)
|
||||
{
|
||||
if(vis[v]==false)
|
||||
push_vertex(v,st,vis,adj);
|
||||
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[]:
|
||||
// making new graph (grev) with reverse edges as in adj[]:
|
||||
vector<int> grev[V];
|
||||
for(int i=0;i<V+1;i++)
|
||||
{
|
||||
for(auto j=adj[i].begin();j!=adj[i].end();j++)
|
||||
{
|
||||
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();
|
||||
// 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);
|
||||
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.
|
||||
// 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()
|
||||
{
|
||||
// All critical/corner cases have been taken care of.
|
||||
// Input your required values: (not hardcoded)
|
||||
int main() {
|
||||
int t;
|
||||
cin>>t;
|
||||
while(t--)
|
||||
{
|
||||
int a,b ; //a->number of nodes, b->directed edges.
|
||||
cin>>a>>b;
|
||||
int m,n;
|
||||
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.
|
||||
cin >> t;
|
||||
while (t--) {
|
||||
int a, b; // a->number of nodes, b->directed edges.
|
||||
cin >> a >> b;
|
||||
int m, n;
|
||||
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.
|
||||
{
|
||||
cin>>m>>n; //take input m,n denoting edge from m->n.
|
||||
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:
|
||||
cout<<kosaraju(a, adj)<<endl;
|
||||
// pass number of nodes and adjacency array as parameters to function:
|
||||
cout << kosaraju(a, adj) << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
115
graph/kruskal.cpp
Normal file
115
graph/kruskal.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <iostream>
|
||||
//#include <boost/multiprecision/cpp_int.hpp>
|
||||
// using namespace boost::multiprecision;
|
||||
const int mx = 1e6 + 5;
|
||||
const long int inf = 2e9;
|
||||
typedef long long ll;
|
||||
#define rep(i, n) for (i = 0; i < n; i++)
|
||||
#define repp(i, a, b) for (i = a; i <= b; i++)
|
||||
#define pii pair<int, int>
|
||||
#define vpii vector<pii>
|
||||
#define vi vector<int>
|
||||
#define vll vector<ll>
|
||||
#define r(x) scanf("%d", &x)
|
||||
#define rs(s) scanf("%s", s)
|
||||
#define gc getchar_unlocked
|
||||
#define pc putchar_unlocked
|
||||
#define mp make_pair
|
||||
#define pb push_back
|
||||
#define lb lower_bound
|
||||
#define ub upper_bound
|
||||
#define endl "\n"
|
||||
#define fast \
|
||||
ios_base::sync_with_stdio(false); \
|
||||
cin.tie(NULL); \
|
||||
cout.tie(NULL);
|
||||
using namespace std;
|
||||
void in(int &x) {
|
||||
register int c = gc();
|
||||
x = 0;
|
||||
int neg = 0;
|
||||
for (; ((c < 48 || c > 57) && c != '-'); c = gc())
|
||||
;
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = gc();
|
||||
}
|
||||
for (; c > 47 && c < 58; c = gc()) {
|
||||
x = (x << 1) + (x << 3) + c - 48;
|
||||
}
|
||||
if (neg)
|
||||
x = -x;
|
||||
}
|
||||
void out(int n) {
|
||||
int N = n, rev, count = 0;
|
||||
rev = N;
|
||||
if (N == 0) {
|
||||
pc('0');
|
||||
return;
|
||||
}
|
||||
while ((rev % 10) == 0) {
|
||||
count++;
|
||||
rev /= 10;
|
||||
}
|
||||
rev = 0;
|
||||
while (N != 0) {
|
||||
rev = (rev << 3) + (rev << 1) + N % 10;
|
||||
N /= 10;
|
||||
}
|
||||
while (rev != 0) {
|
||||
pc(rev % 10 + '0');
|
||||
rev /= 10;
|
||||
}
|
||||
while (count--) pc('0');
|
||||
}
|
||||
ll parent[mx], arr[mx], node, edge;
|
||||
vector<pair<ll, pair<ll, ll>>> v;
|
||||
void initial() {
|
||||
int i;
|
||||
rep(i, node + edge) parent[i] = i;
|
||||
}
|
||||
int root(int i) {
|
||||
while (parent[i] != i) {
|
||||
parent[i] = parent[parent[i]];
|
||||
i = parent[i];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
void join(int x, int y) {
|
||||
int root_x = root(x); // Disjoint set union by rank
|
||||
int root_y = root(y);
|
||||
parent[root_x] = root_y;
|
||||
}
|
||||
ll kruskal() {
|
||||
ll mincost = 0, i, x, y;
|
||||
rep(i, edge) {
|
||||
x = v[i].second.first;
|
||||
y = v[i].second.second;
|
||||
if (root(x) != root(y)) {
|
||||
mincost += v[i].first;
|
||||
join(x, y);
|
||||
}
|
||||
}
|
||||
return mincost;
|
||||
}
|
||||
int main() {
|
||||
fast;
|
||||
while (1) {
|
||||
int i, j, from, to, cost, totalcost = 0;
|
||||
cin >> node >> edge; // Enter the nodes and edges
|
||||
if (node == 0 && edge == 0)
|
||||
break; // Enter 0 0 to break out
|
||||
initial(); // Initialise the parent array
|
||||
rep(i, edge) {
|
||||
cin >> from >> to >> cost;
|
||||
v.pb(mp(cost, mp(from, to)));
|
||||
totalcost += cost;
|
||||
}
|
||||
sort(v.begin(), v.end());
|
||||
// rep(i,v.size())
|
||||
// cout<<v[i].first<<" ";
|
||||
cout << kruskal() << endl;
|
||||
v.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -7,19 +7,16 @@ using namespace std;
|
||||
// Resource : https://cp-algorithms.com/graph/lca_binary_lifting.html
|
||||
const int N = 1005;
|
||||
const int LG = log2(N) + 1;
|
||||
struct lca
|
||||
{
|
||||
struct lca {
|
||||
int n;
|
||||
vector<int> adj[N]; // Graph
|
||||
int up[LG][N]; // build this table
|
||||
int level[N]; // get the levels of all of them
|
||||
vector<int> adj[N]; // Graph
|
||||
int up[LG][N]; // build this table
|
||||
int level[N]; // get the levels of all of them
|
||||
|
||||
lca(int n_): n(n_)
|
||||
{
|
||||
lca(int n_) : n(n_) {
|
||||
memset(up, -1, sizeof(up));
|
||||
memset(level, 0, sizeof(level));
|
||||
for (int i = 0; i < n - 1; ++i)
|
||||
{
|
||||
for (int i = 0; i < n - 1; ++i) {
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
a--;
|
||||
@@ -31,77 +28,59 @@ struct lca
|
||||
dfs(0, -1);
|
||||
build();
|
||||
}
|
||||
void verify()
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
void verify() {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
cout << i << " : level: " << level[i] << endl;
|
||||
}
|
||||
cout << endl;
|
||||
for (int i = 0; i < LG; ++i)
|
||||
{
|
||||
for (int i = 0; i < LG; ++i) {
|
||||
cout << "Power:" << i << ": ";
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
for (int j = 0; j < n; ++j) {
|
||||
cout << up[i][j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void build()
|
||||
{
|
||||
for (int i = 1; i < LG; ++i)
|
||||
{
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
if (up[i - 1][j] != -1)
|
||||
{
|
||||
void build() {
|
||||
for (int i = 1; i < LG; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
if (up[i - 1][j] != -1) {
|
||||
up[i][j] = up[i - 1][up[i - 1][j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dfs(int node, int par)
|
||||
{
|
||||
void dfs(int node, int par) {
|
||||
up[0][node] = par;
|
||||
for (auto i: adj[node])
|
||||
{
|
||||
if (i != par)
|
||||
{
|
||||
for (auto i : adj[node]) {
|
||||
if (i != par) {
|
||||
level[i] = level[node] + 1;
|
||||
dfs(i, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
int query(int u, int v)
|
||||
{
|
||||
int query(int u, int v) {
|
||||
u--;
|
||||
v--;
|
||||
if (level[v] > level[u])
|
||||
{
|
||||
if (level[v] > level[u]) {
|
||||
swap(u, v);
|
||||
}
|
||||
// u is at the bottom.
|
||||
int dist = level[u] - level[v];
|
||||
// Go up this much distance
|
||||
for (int i = LG - 1; i >= 0; --i)
|
||||
{
|
||||
if (dist & (1 << i))
|
||||
{
|
||||
for (int i = LG - 1; i >= 0; --i) {
|
||||
if (dist & (1 << i)) {
|
||||
u = up[i][u];
|
||||
}
|
||||
}
|
||||
if (u == v)
|
||||
{
|
||||
if (u == v) {
|
||||
return u;
|
||||
}
|
||||
assert(level[u] == level[v]);
|
||||
for (int i = LG - 1; i >= 0; --i)
|
||||
{
|
||||
if (up[i][u] != up[i][v])
|
||||
{
|
||||
for (int i = LG - 1; i >= 0; --i) {
|
||||
if (up[i][u] != up[i][v]) {
|
||||
u = up[i][u];
|
||||
v = up[i][v];
|
||||
}
|
||||
@@ -111,10 +90,9 @@ struct lca
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int n; // number of nodes in the tree.
|
||||
lca l(n); // will take the input in the format given
|
||||
int main() {
|
||||
int n; // number of nodes in the tree.
|
||||
lca l(n); // will take the input in the format given
|
||||
// n-1 edges of the form
|
||||
// a b
|
||||
// Use verify function to see.
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
* Copyright: 2020, Open-Source
|
||||
* Last Modified: May 25, 2020
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <tuple>
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
// std::max capacity of node in graph
|
||||
const int MAXN = 505;
|
||||
class Graph {
|
||||
@@ -21,13 +21,13 @@ class Graph {
|
||||
int total_nodes;
|
||||
int total_edges, source, sink;
|
||||
int parent[MAXN];
|
||||
std::vector <std::tuple <int, int, int> >edge_participated;
|
||||
std::bitset <MAXN> visited;
|
||||
std::vector<std::tuple<int, int, int> > edge_participated;
|
||||
std::bitset<MAXN> visited;
|
||||
int max_flow = 0;
|
||||
bool bfs(int source, int sink) { // to find the augmented - path
|
||||
memset(parent, -1, sizeof(parent));
|
||||
visited.reset();
|
||||
std::queue<int>q;
|
||||
std::queue<int> q;
|
||||
q.push(source);
|
||||
bool is_path_found = false;
|
||||
while (q.empty() == false && is_path_found == false) {
|
||||
@@ -49,9 +49,7 @@ class Graph {
|
||||
}
|
||||
|
||||
public:
|
||||
Graph() {
|
||||
memset(residual_capacity, 0, sizeof(residual_capacity));
|
||||
}
|
||||
Graph() { memset(residual_capacity, 0, sizeof(residual_capacity)); }
|
||||
void set_graph(void) {
|
||||
std::cin >> total_nodes >> total_edges >> source >> sink;
|
||||
for (int start, destination, capacity_, i = 0; i < total_edges; ++i) {
|
||||
@@ -71,7 +69,7 @@ class Graph {
|
||||
}
|
||||
current_node = sink;
|
||||
max_flow += flow;
|
||||
while ( current_node != source ) {
|
||||
while (current_node != source) {
|
||||
int parent_ = parent[current_node];
|
||||
residual_capacity[parent_][current_node] -= flow;
|
||||
residual_capacity[current_node][parent_] += flow;
|
||||
@@ -83,23 +81,21 @@ class Graph {
|
||||
for (int i = 0; i < total_nodes; ++i) {
|
||||
for (int j = 0; j < total_nodes; ++j) {
|
||||
if (capacity[i][j] &&
|
||||
residual_capacity[i][j] < capacity[i][j]) {
|
||||
edge_participated.push_back(
|
||||
std::make_tuple(i, j,
|
||||
capacity[i][j]-residual_capacity[i][j]));
|
||||
residual_capacity[i][j] < capacity[i][j]) {
|
||||
edge_participated.push_back(std::make_tuple(
|
||||
i, j, capacity[i][j] - residual_capacity[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "\nNodes : " << total_nodes
|
||||
<< "\nMax flow: " << max_flow
|
||||
<< "\nEdge present in flow: " << edge_participated.size()
|
||||
<< '\n';
|
||||
std::cout<< "\nSource\tDestination\tCapacity\total_nodes";
|
||||
for (auto&edge_data : edge_participated) {
|
||||
std::cout << "\nNodes : " << total_nodes << "\nMax flow: " << max_flow
|
||||
<< "\nEdge present in flow: " << edge_participated.size()
|
||||
<< '\n';
|
||||
std::cout << "\nSource\tDestination\tCapacity\total_nodes";
|
||||
for (auto& edge_data : edge_participated) {
|
||||
int source, destination, capacity_;
|
||||
std::tie(source, destination, capacity_) = edge_data;
|
||||
std::cout << source << "\t" << destination << "\t\t"
|
||||
<< capacity_ <<'\t';
|
||||
std::cout << source << "\t" << destination << "\t\t" << capacity_
|
||||
<< '\t';
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -119,4 +115,3 @@ int main(void) {
|
||||
graph.print_flow_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// C++ program to implement Prim's Algorithm
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
const int MAX = 1e4 + 5;
|
||||
typedef std:: pair<int, int> PII;
|
||||
typedef std::pair<int, int> PII;
|
||||
|
||||
bool marked[MAX];
|
||||
std:: vector <PII> adj[MAX];
|
||||
std::vector<PII> adj[MAX];
|
||||
|
||||
int prim(int x) {
|
||||
// priority queue to maintain edges with respect to weights
|
||||
std:: priority_queue<PII, std:: vector<PII>, std:: greater<PII> > Q;
|
||||
std::priority_queue<PII, std::vector<PII>, std::greater<PII> > Q;
|
||||
int y;
|
||||
int minimumCost = 0;
|
||||
PII p;
|
||||
|
||||
Q.push(std:: make_pair(0, x));
|
||||
Q.push(std::make_pair(0, x));
|
||||
while (!Q.empty()) {
|
||||
// Select the edge with minimum weight
|
||||
p = Q.top();
|
||||
@@ -40,19 +40,19 @@ int main() {
|
||||
int nodes, edges, x, y;
|
||||
int weight, minimumCost;
|
||||
|
||||
std:: cin >> nodes >> edges; // number of nodes & edges in graph
|
||||
std::cin >> nodes >> edges; // number of nodes & edges in graph
|
||||
if (nodes == 0 || edges == 0)
|
||||
return 0;
|
||||
|
||||
// Edges with their nodes & weight
|
||||
for (int i = 0; i < edges; ++i) {
|
||||
std::cin >> x >> y >> weight;
|
||||
adj[x].push_back(std:: make_pair(weight, y));
|
||||
adj[y].push_back(std:: make_pair(weight, x));
|
||||
adj[x].push_back(std::make_pair(weight, y));
|
||||
adj[y].push_back(std::make_pair(weight, x));
|
||||
}
|
||||
|
||||
// Selecting 1 as the starting node
|
||||
minimumCost = prim(1);
|
||||
std:: cout << minimumCost << std:: endl;
|
||||
std::cout << minimumCost << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
47
graph/topological_sort.cpp
Normal file
47
graph/topological_sort.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
int n, m; // For number of Vertices (V) and number of edges (E)
|
||||
vector<vector<int>> G;
|
||||
vector<bool> visited;
|
||||
vector<int> ans;
|
||||
|
||||
void dfs(int v) {
|
||||
visited[v] = true;
|
||||
for (int u : G[v]) {
|
||||
if (!visited[u])
|
||||
dfs(u);
|
||||
}
|
||||
ans.push_back(v);
|
||||
}
|
||||
|
||||
void topological_sort() {
|
||||
visited.assign(n, false);
|
||||
ans.clear();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!visited[i])
|
||||
dfs(i);
|
||||
}
|
||||
reverse(ans.begin(), ans.end());
|
||||
}
|
||||
int main() {
|
||||
cout << "Enter the number of vertices and the number of directed edges\n";
|
||||
cin >> n >> m;
|
||||
int x, y;
|
||||
G.resize(n, vector<int>());
|
||||
for (int i = 0; i < n; ++i) {
|
||||
cin >> x >> y;
|
||||
x--, y--; // to convert 1-indexed to 0-indexed
|
||||
G[x].push_back(y);
|
||||
}
|
||||
topological_sort();
|
||||
cout << "Topological Order : \n";
|
||||
for (int v : ans) {
|
||||
cout << v + 1
|
||||
<< ' '; // converting zero based indexing back to one based.
|
||||
}
|
||||
cout << '\n';
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
int *topoSortKahn(int N, std::vector<int> adj[]);
|
||||
|
||||
@@ -13,7 +13,7 @@ int main() {
|
||||
return 0;
|
||||
int u, v;
|
||||
|
||||
std::vector<int>graph[nodes];
|
||||
std::vector<int> graph[nodes];
|
||||
// create graph
|
||||
// example
|
||||
// 6 6
|
||||
@@ -31,23 +31,23 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
int* topoSortKahn(int V, std::vector<int> adj[]) {
|
||||
std::vector<bool>vis(V+1, false);
|
||||
std::vector<int>deg(V+1, 0);
|
||||
int *topoSortKahn(int V, std::vector<int> adj[]) {
|
||||
std::vector<bool> vis(V + 1, false);
|
||||
std::vector<int> deg(V + 1, 0);
|
||||
for (int i = 0; i < V; i++) {
|
||||
for (int j = 0; j < adj[i].size(); j++) {
|
||||
deg[adj[i][j]]++;
|
||||
}
|
||||
}
|
||||
std::queue<int>q;
|
||||
std::queue<int> q;
|
||||
for (int i = 0; i < V; i++) {
|
||||
if (deg[i] == 0) {
|
||||
q.push(i);
|
||||
vis[i] = true;
|
||||
}
|
||||
}
|
||||
int *arr = new int[V+1];
|
||||
memset(arr, 0, V+1);
|
||||
int *arr = new int[V + 1];
|
||||
memset(arr, 0, V + 1);
|
||||
int count = 0;
|
||||
while (!q.empty()) {
|
||||
int cur = q.front();
|
||||
|
||||
Reference in New Issue
Block a user