From ecd7fb35bbed526fd60d7938ba3dbbc0f6ee3f52 Mon Sep 17 00:00:00 2001 From: sumeshpandit <32913357+sumeshpandit@users.noreply.github.com> Date: Sat, 17 Oct 2020 14:05:21 +0530 Subject: [PATCH] Create tarjan's algorithm.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tarjan’s Algorithm to find Strongly Connected Components --- C++/tarjan's algorithm.cpp | 166 +++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 C++/tarjan's algorithm.cpp diff --git a/C++/tarjan's algorithm.cpp b/C++/tarjan's algorithm.cpp new file mode 100644 index 0000000..95bca67 --- /dev/null +++ b/C++/tarjan's algorithm.cpp @@ -0,0 +1,166 @@ +// A C++ program to find strongly connected components in a given +// directed graph using Tarjan's algorithm (single DFS) +#include +#include +#include +#define NIL -1 +using namespace std; + +// A class that represents an directed graph +class Graph +{ + int V; // No. of vertices + list *adj; // A dynamic array of adjacency lists + + // A Recursive DFS based function used by SCC() + void SCCUtil(int u, int disc[], int low[], + stack *st, bool stackMember[]); +public: + Graph(int V); // Constructor + void addEdge(int v, int w); // function to add an edge to graph + void SCC(); // prints strongly connected components +}; + +Graph::Graph(int V) +{ + this->V = V; + adj = new list[V]; +} + +void Graph::addEdge(int v, int w) +{ + adj[v].push_back(w); +} + +void Graph::SCCUtil(int u, int disc[], int low[], stack *st, + bool stackMember[]) +{ + static int time = 0; + + // Initialize discovery time and low value + disc[u] = low[u] = ++time; + st->push(u); + stackMember[u] = true; + + // Go through all vertices adjacent to this + list::iterator i; + for (i = adj[u].begin(); i != adj[u].end(); ++i) + { + int v = *i; // v is current adjacent of 'u' + + // If v is not visited yet, then recur for it + if (disc[v] == -1) + { + SCCUtil(v, disc, low, st, stackMember); + + // Check if the subtree rooted with 'v' has a + // connection to one of the ancestors of 'u' + // Case 1 (per above discussion on Disc and Low value) + low[u] = min(low[u], low[v]); + } + + // Update low value of 'u' only of 'v' is still in stack + // (i.e. it's a back edge, not cross edge). + // Case 2 (per above discussion on Disc and Low value) + else if (stackMember[v] == true) + low[u] = min(low[u], disc[v]); + } + + // head node found, pop the stack and print an SCC + int w = 0; // To store stack extracted vertices + if (low[u] == disc[u]) + { + while (st->top() != u) + { + w = (int) st->top(); + cout << w << " "; + stackMember[w] = false; + st->pop(); + } + w = (int) st->top(); + cout << w << "\n"; + stackMember[w] = false; + st->pop(); + } +} + +// The function to do DFS traversal. It uses SCCUtil() +void Graph::SCC() +{ + int *disc = new int[V]; + int *low = new int[V]; + bool *stackMember = new bool[V]; + stack *st = new stack(); + + // Initialize disc and low, and stackMember arrays + for (int i = 0; i < V; i++) + { + disc[i] = NIL; + low[i] = NIL; + stackMember[i] = false; + } + + // Call the recursive helper function to find strongly + // connected components in DFS tree with vertex 'i' + for (int i = 0; i < V; i++) + if (disc[i] == NIL) + SCCUtil(i, disc, low, st, stackMember); +} + +// Driver program to test above function +int main() +{ + cout << "\nSCCs in first graph \n"; + Graph g1(5); + g1.addEdge(1, 0); + g1.addEdge(0, 2); + g1.addEdge(2, 1); + g1.addEdge(0, 3); + g1.addEdge(3, 4); + g1.SCC(); + + cout << "\nSCCs in second graph \n"; + Graph g2(4); + g2.addEdge(0, 1); + g2.addEdge(1, 2); + g2.addEdge(2, 3); + g2.SCC(); + + cout << "\nSCCs in third graph \n"; + Graph g3(7); + g3.addEdge(0, 1); + g3.addEdge(1, 2); + g3.addEdge(2, 0); + g3.addEdge(1, 3); + g3.addEdge(1, 4); + g3.addEdge(1, 6); + g3.addEdge(3, 5); + g3.addEdge(4, 5); + g3.SCC(); + + cout << "\nSCCs in fourth graph \n"; + Graph g4(11); + g4.addEdge(0,1);g4.addEdge(0,3); + g4.addEdge(1,2);g4.addEdge(1,4); + g4.addEdge(2,0);g4.addEdge(2,6); + g4.addEdge(3,2); + g4.addEdge(4,5);g4.addEdge(4,6); + g4.addEdge(5,6);g4.addEdge(5,7);g4.addEdge(5,8);g4.addEdge(5,9); + g4.addEdge(6,4); + g4.addEdge(7,9); + g4.addEdge(8,9); + g4.addEdge(9,8); + g4.SCC(); + + cout << "\nSCCs in fifth graph \n"; + Graph g5(5); + g5.addEdge(0,1); + g5.addEdge(1,2); + g5.addEdge(2,3); + g5.addEdge(2,4); + g5.addEdge(3,0); + g5.addEdge(4,2); + g5.SCC(); + + return 0; +}