# Comparison between Tarjan’s and Kosaraju’s Algorithm

Tarjan’s Algorithm: The Tarjan’s Algorithm is an efficient graph algorithm that is used to find the Strongly Connected Component(SCC) in a directed graph by using only one DFS traversal in linear time complexity.

Working:

• Perform a DFS traversal over the nodes so that the sub-trees of the Strongly Connected Components are removed when they are encountered.
• Then two values are assigned:
• The first value is the counter value when the node is explored for the first time.
• Second value stores the lowest node value reachable from the initial node which is not part of another SCC.
• When the nodes are explored, they are pushed into a stack.
• If there are any unexplored children of a node are left, they are explored and the assigned value is respectively updated.

Below is the program to find the SCC of the given graph using Tarjan’s Algorithm:

## C++

 `// C++ program to find the SCC using``// Tarjan's algorithm (single DFS)``#include ``#include ``#include ``#define NIL -1``using` `namespace` `std;` `// A class that represents``// an directed graph``class` `Graph {``    ``// No. of vertices``    ``int` `V;` `    ``// A dynamic array of adjacency lists``    ``list<``int``>* adj;` `    ``// A Recursive DFS based function``    ``// used by SCC()``    ``void` `SCCUtil(``int` `u, ``int` `disc[],``                 ``int` `low[], stack<``int``>* st,``                 ``bool` `stackMember[]);` `public``:``    ``// Member functions``    ``Graph(``int` `V);``    ``void` `addEdge(``int` `v, ``int` `w);``    ``void` `SCC();``};` `// Constructor``Graph::Graph(``int` `V)``{``    ``this``->V = V;``    ``adj = ``new` `list<``int``>[V];``}` `// Function to add an edge to the graph``void` `Graph::addEdge(``int` `v, ``int` `w)``{``    ``adj[v].push_back(w);``}` `// Recursive function to finds the SCC``// using DFS traversal``void` `Graph::SCCUtil(``int` `u, ``int` `disc[],``                    ``int` `low[], stack<``int``>* 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<``int``>::iterator i;` `    ``for` `(i = adj[u].begin();``         ``i != adj[u].end(); ++i) {``        ``// v is current adjacent of 'u'``        ``int` `v = *i;` `        ``// 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 connection to``            ``// one of the ancestors of 'u'``            ``low[u] = min(low[u], low[v]);``        ``}` `        ``// Update low value of 'u' only of``        ``// 'v' is still in stack``        ``else` `if` `(stackMember[v] == ``true``)``            ``low[u] = min(low[u], disc[v]);``    ``}` `    ``// head node found, pop the stack``    ``// and print an SCC` `    ``// Store stack extracted vertices``    ``int` `w = 0;` `    ``// If low[u] and disc[u]``    ``if` `(low[u] == disc[u]) {``        ``// Until stack st is empty``        ``while` `(st->top() != u) {``            ``w = (``int``)st->top();` `            ``// Print the node``            ``cout << w << ``" "``;``            ``stackMember[w] = ``false``;``            ``st->pop();``        ``}``        ``w = (``int``)st->top();``        ``cout << w << ``"\n"``;``        ``stackMember[w] = ``false``;``        ``st->pop();``    ``}``}` `// Function to find the SCC in the graph``void` `Graph::SCC()``{``    ``// Stores the discovery times of``    ``// the nodes``    ``int``* disc = ``new` `int``[V];` `    ``// Stores the nodes with least``    ``// discovery time``    ``int``* low = ``new` `int``[V];` `    ``// Checks whether a node is in``    ``// the stack or not``    ``bool``* stackMember = ``new` `bool``[V];` `    ``// Stores all the connected ancestors``    ``stack<``int``>* st = ``new` `stack<``int``>();` `    ``// Initialize disc and low,``    ``// and stackMember arrays``    ``for` `(``int` `i = 0; i < V; i++) {``        ``disc[i] = NIL;``        ``low[i] = NIL;``        ``stackMember[i] = ``false``;``    ``}` `    ``// Recursive helper function to``    ``// find the SCC in DFS tree with``    ``// vertex 'i'``    ``for` `(``int` `i = 0; i < V; i++) {` `        ``// If current node is not``        ``// yet visited``        ``if` `(disc[i] == NIL) {``            ``SCCUtil(i, disc, low,``                    ``st, stackMember);``        ``}``    ``}``}` `// Driver Code``int` `main()``{``    ``// Given a graph``    ``Graph g1(5);``    ``g1.addEdge(1, 0);``    ``g1.addEdge(0, 2);``    ``g1.addEdge(2, 1);``    ``g1.addEdge(0, 3);``    ``g1.addEdge(3, 4);` `    ``// Function Call to find SCC using``    ``// Tarjan's Algorithm``    ``g1.SCC();` `    ``return` `0;``}`

## Java

 `// java program to find the SCC using``// Tarjan's algorithm (single DFS)``import` `java.io.*;``import` `java.util.*;` `// A class that represents``// an directed graph``class` `GFG {``    ``// No. of vertices``    ``private` `int` `V;``    ``// A Dynamic array of adjacency lists``    ``private` `LinkedList[] adj;``    ``private` `int` `time;``    ``// Constructor``    ``GFG(``int` `V) {``        ``this``.V = V;``        ``adj = ``new` `LinkedList[V];``        ``for` `(``int` `i = ``0``; i < V; i++) {``            ``adj[i] = ``new` `LinkedList<>();``        ``}``    ``}``    ``// Function to add an edge to the graph``    ``void` `addEdge(``int` `v, ``int` `w) {``        ``adj[v].add(w);``    ``}``    ``// Recursive function to find the SCC ``    ``// using DFS traversal``    ``void` `SCCUtil(``int` `u, ``int``[] disc, ``int``[] low, Stack st, ``boolean``[] stackMember) {``        ``// Initialize discovery time ``        ``// and low value``        ``disc[u] = low[u] = ++time;``        ``st.push(u);``        ``stackMember[u] = ``true``;``        ``// Go through all vertices ``        ``// adjacent to this``        ``for` `(``int` `v : adj[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'``                ``low[u] = Math.min(low[u], low[v]);``            ``}``            ``// Update low value of 'u' only of ``            ``// 'v' is still in stack``            ``else` `if` `(stackMember[v]) {``                ``low[u] = Math.min(low[u], disc[v]);``            ``}``        ``}``        ``// Head node found, pop the stack ``        ``// and print an SCC``        ``if` `(low[u] == disc[u]) {``            ``int` `w;``            ``// Until stack st is empty``            ``do` `{``                ``w = st.pop();``                ``// Print the node``                ``System.out.print(w + ``" "``);``                ``stackMember[w] = ``false``;``            ``} ``while` `(w != u);``            ``System.out.println();``        ``}``    ``}``    ``// Function to find the SCC in the graph``    ``void` `SCC() {``        ``// Stores the discovery times of ``        ``// the nodes``        ``int``[] disc = ``new` `int``[V];``        ``// Stores the nodes with the ``        ``// least discovery time``        ``int``[] low = ``new` `int``[V];``        ``// Checks whether a node is in ``        ``// the stack or not``        ``boolean``[] stackMember = ``new` `boolean``[V];``        ``// Stores all the connected ancestors``        ``Stack st = ``new` `Stack<>();``        ``// Initialize disc and low ``        ``// and stackMember arrays``        ``Arrays.fill(disc, -``1``);``        ``Arrays.fill(low, -``1``);``        ``Arrays.fill(stackMember, ``false``);``        ``// Recursive helper function to ``        ``// find the SCC in DFS tree with ``        ``// vertex 'i'``        ``for` `(``int` `i = ``0``; i < V; i++) {``            ``// If the current node is not ``            ``// yet visited``            ``if` `(disc[i] == -``1``) {``                ``SCCUtil(i, disc, low, st, stackMember);``            ``}``        ``}``    ``}``}``// Driver Code``public` `class` `Main {``    ``public` `static` `void` `main(String[] args) {``        ``// Given a graph``        ``GFG g1 = ``new` `GFG(``5``);``        ``g1.addEdge(``1``, ``0``);``        ``g1.addEdge(``0``, ``2``);``        ``g1.addEdge(``2``, ``1``);``        ``g1.addEdge(``0``, ``3``);``        ``g1.addEdge(``3``, ``4``);``        ``// Function Call to find SCC using ``        ``// Tarjan's Algorithm``        ``g1.SCC();``    ``}``}`

## Python3

 `from` `collections ``import` `defaultdict`  `class` `Graph:``    ``def` `__init__(``self``, vertices):``        ``self``.V ``=` `vertices``        ``self``.adj ``=` `defaultdict(``list``)``        ``self``.time ``=` `0` `    ``def` `add_edge(``self``, u, v):``        ``self``.adj[u].append(v)` `    ``def` `SCCUtil(``self``, u, disc, low, stackMember, st):``        ``disc[u] ``=` `self``.time``        ``low[u] ``=` `self``.time``        ``self``.time ``+``=` `1``        ``stackMember[u] ``=` `True``        ``st.append(u)` `        ``for` `v ``in` `self``.adj[u]:``            ``if` `disc[v] ``=``=` `-``1``:``                ``self``.SCCUtil(v, disc, low, stackMember, st)``                ``low[u] ``=` `min``(low[u], low[v])``            ``elif` `stackMember[v]:``                ``low[u] ``=` `min``(low[u], disc[v])` `        ``w ``=` `-``1`  `# To store stack extracted vertices``        ``if` `low[u] ``=``=` `disc[u]:``            ``while` `w !``=` `u:``                ``w ``=` `st.pop()``                ``print``(w, end``=``' '``)``                ``stackMember[w] ``=` `False``            ``print``()` `    ``def` `SCC(``self``):``        ``disc ``=` `[``-``1``] ``*` `self``.V``        ``low ``=` `[``-``1``] ``*` `self``.V``        ``stackMember ``=` `[``False``] ``*` `self``.V``        ``st ``=` `[]` `        ``for` `i ``in` `range``(``self``.V):``            ``if` `disc[i] ``=``=` `-``1``:``                ``self``.SCCUtil(i, disc, low, stackMember, st)`  `g ``=` `Graph(``5``)``g.add_edge(``1``, ``0``)``g.add_edge(``0``, ``2``)``g.add_edge(``2``, ``1``)``g.add_edge(``0``, ``3``)``g.add_edge(``3``, ``4``)` `g.SCC()`

## C#

 `using` `System;``using` `System.Collections.Generic;` `class` `Graph``{``    ``private` `int` `V;``    ``private` `List<``int``>[] adj;``    ``private` `int` `time;` `    ``public` `Graph(``int` `vertices)``    ``{``        ``V = vertices;``        ``adj = ``new` `List<``int``>[V];``        ``for` `(``int` `i = 0; i < V; i++)``        ``{``            ``adj[i] = ``new` `List<``int``>();``        ``}``        ``time = 0;``    ``}` `    ``public` `void` `AddEdge(``int` `v, ``int` `w)``    ``{``        ``adj[v].Add(w);``    ``}` `    ``private` `void` `SCCUtil(``int` `u, ``int``[] disc, ``int``[] low, Stack<``int``> st, ``bool``[] stackMember)``    ``{``        ``disc[u] = low[u] = ++time;``        ``st.Push(u);``        ``stackMember[u] = ``true``;` `        ``foreach` `(``int` `v ``in` `adj[u])``        ``{``            ``if` `(disc[v] == -1)``            ``{``                ``SCCUtil(v, disc, low, st, stackMember);``                ``low[u] = Math.Min(low[u], low[v]);``            ``}``            ``else` `if` `(stackMember[v])``            ``{``                ``low[u] = Math.Min(low[u], disc[v]);``            ``}``        ``}` `        ``if` `(low[u] == disc[u])``        ``{``            ``while` `(st.Count > 0)``            ``{``                ``int` `w = st.Pop();``                ``stackMember[w] = ``false``;``                ``Console.Write(w);``                ``if` `(w == u)``                ``{``                    ``Console.WriteLine();``                    ``break``;``                ``}``                ``else``                ``{``                    ``Console.Write(``" "``);``                ``}``            ``}``        ``}``    ``}` `    ``public` `void` `SCC()``    ``{``        ``int``[] disc = ``new` `int``[V];``        ``int``[] low = ``new` `int``[V];``        ``bool``[] stackMember = ``new` `bool``[V];``        ``Stack<``int``> st = ``new` `Stack<``int``>();` `        ``for` `(``int` `i = 0; i < V; i++)``        ``{``            ``disc[i] = -1;``            ``low[i] = -1;``            ``stackMember[i] = ``false``;``        ``}` `        ``for` `(``int` `i = 0; i < V; i++)``        ``{``            ``if` `(disc[i] == -1)``            ``{``                ``SCCUtil(i, disc, low, st, stackMember);``            ``}``        ``}``    ``}` `    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``Graph g1 = ``new` `Graph(5);``        ``g1.AddEdge(1, 0);``        ``g1.AddEdge(0, 2);``        ``g1.AddEdge(2, 1);``        ``g1.AddEdge(0, 3);``        ``g1.AddEdge(3, 4);``        ``g1.SCC();``    ``}``}`

## Javascript

 `// javascript program to find the SCC using``// Tarjan's algorithm (single DFS)``let NIL = -1``let time = 0;` `// A class that represents``// an directed graph``class Graph {``    ` `    ``constructor(V){``        ` `        ``// Number of vertices``        ``this``.V = V;``        ` `        ``// Number of neighbours``        ``this``.adj = ``new` `Array(V);``        ``for``(let i = 0; i < V; i++){``            ``this``.adj[i] = ``new` `Array();``        ``}``    ``}``    ` `    ` `    ``// Function to add an edge to the graph``    ``addEdge(v, w)``    ``{``        ``this``.adj[v].push(w);``    ``}` `    ``// Recursive function to finds the SCC``    ``// using DFS traversal``    ``SCCUtil(u, disc, low, st, stackMember)``    ``{``        `  `        ``// Initialize discovery time``        ``// and low value``        ``disc[u] = low[u] = ++time;``        ``st.push(u);``        ``stackMember[u] = ``true``;` `        ``// Go through all vertices``        ``// adjacent to this` `        ``for` `(let i = 0; i < ``this``.adj[u].length; i++){``            ``// v is current adjacent of 'u'``            ``let v = ``this``.adj[u][i];` `            ``// If v is not visited yet,``            ``// then recur for it``            ``if` `(disc[v] == -1) {``                ``this``.SCCUtil(v, disc, low, st, stackMember);` `                ``// Check if the subtree rooted``                ``// with 'v' has connection to``                ``// one of the ancestors of 'u'``                ``low[u] = Math.min(low[u], low[v]);``            ``}` `            ``// Update low value of 'u' only of``            ``// 'v' is still in stack``            ``else` `if` `(stackMember[v] == ``true``)``                ``low[u] = Math.min(low[u], disc[v]);``        ``}` `        ``// head node found, pop the stack``        ``// and print an SCC` `        ``// Store stack extracted vertices``        ``let w = 0;` `        ``// If low[u] and disc[u]``        ``if` `(low[u] == disc[u]) {``            ``// Until stack st is empty``            ``while` `(st[st.length-1] != u) {``                ``w = st[st.length-1];` `                ``// Print the node``                ``process.stdout.write(w + ``" "``);``                ``stackMember[w] = ``false``;``                ``st.pop();``            ``}``            ``w = st[st.length-1];``            ``process.stdout.write(w + ``"\n"``);``            ``stackMember[w] = ``false``;``            ``st.pop();``        ``}``    ``}``    `  `    ``// Function to find the SCC in the graph``    ``SCC()``    ``{``        ``// Stores the discovery times of``        ``// the nodes``        ``let disc = ``new` `Array(``this``.V);` `        ``// Stores the nodes with least``        ``// discovery time``        ``let low = ``new` `Array(``this``.V);``    `  `        ``// Checks whether a node is in``        ``// the stack or not``        ``let stackMember = ``new` `Array(``this``.V);` `        ``// Stores all the connected ancestors``        ``let st = [];` `        ``// Initialize disc and low,``        ``// and stackMember arrays``        ``for` `(let i = 0; i < ``this``.V; i++) {``            ``disc[i] = NIL;``            ``low[i] = NIL;``            ``stackMember[i] = ``false``;``        ``}` `        ``// Recursive helper function to``        ``// find the SCC in DFS tree with``        ``// vertex 'i'``        ``for` `(let i = 0; i < ``this``.V; i++) {` `            ``// If current node is not``            ``// yet visited``            ``if` `(disc[i] == NIL) {``                ``this``.SCCUtil(i, disc, low, st, stackMember);``            ``}``        ``}``    ``}` `};`  `// Driver Code` `// Given a graph``let g1 = ``new` `Graph(5);``g1.addEdge(1, 0);``g1.addEdge(0, 2);``g1.addEdge(2, 1);``g1.addEdge(0, 3);``g1.addEdge(3, 4);` `// Function Call to find SCC using``// Tarjan's Algorithm``g1.SCC();` `// The code is contributed by Nidhi goel. `

Output
```4
3
1 2 0

```

Kosaraju’s Algorithm: The Kosaraju’s Algorithm is also a Depth First Search based algorithm which is used to find the SCC in a directed graph in linear time complexity. The basic concept of this algorithm is that if we are able to arrive at vertex v initially starting from vertex u, then we should be able to arrive at vertex u starting from vertex v, and if this is the situation, we can say and conclude that vertices u and v are strongly connected, and they are in the strongly connected sub-graph.

Working:

• Perform a DFS traversal on the given graph, keeping track of the finish times of each node. This process can be performed by using a stack.
• When the procedure of running the DFS traversal over the graph finishes, put the source vertex on the stack. In this way, the node with the highest finishing time will be at the top of the stack.
• Reverse the original graph by using an Adjacency List.
• Then perform another DFS traversal on the reversed graph with the source vertex as the vertex on the top of the stack. When the DFS running on the reversed graph finishes, all the nodes that are visited will form one strongly connected component.
• If any more nodes are left or remain unvisited, this signifies the presence of more than one strongly connected component on the graph.
• So pop the vertices from the top of the stack until a valid unvisited node is found. This will have the highest finishing time of all currently unvisited nodes.

Below is the program to find the SCC of the given graph using Kosaraju’s Algorithm:

## C++

 `// C++ program to print the SCC of the``// graph using Kosaraju's Algorithm``#include ``#include ``#include ``using` `namespace` `std;` `class` `Graph {``    ``// No. of vertices``    ``int` `V;` `    ``// An array of adjacency lists``    ``list<``int``>* adj;` `    ``// Member Functions``    ``void` `fillOrder(``int` `v, ``bool` `visited[],``                   ``stack<``int``>& Stack);``    ``void` `DFSUtil(``int` `v, ``bool` `visited[]);` `public``:``    ``Graph(``int` `V);``    ``void` `addEdge(``int` `v, ``int` `w);``    ``void` `printSCCs();``    ``Graph getTranspose();``};` `// Constructor of class``Graph::Graph(``int` `V)``{``    ``this``->V = V;``    ``adj = ``new` `list<``int``>[V];``}` `// Recursive function to print DFS``// starting from v``void` `Graph::DFSUtil(``int` `v, ``bool` `visited[])``{``    ``// Mark the current node as``    ``// visited and print it``    ``visited[v] = ``true``;``    ``cout << v << ``" "``;` `    ``// Recur for all the vertices``    ``// adjacent to this vertex``    ``list<``int``>::iterator i;` `    ``// Traverse Adjacency List of node v``    ``for` `(i = adj[v].begin();``         ``i != adj[v].end(); ++i) {` `        ``// If child node *i is unvisited``        ``if` `(!visited[*i])``            ``DFSUtil(*i, visited);``    ``}``}` `// Function to get the transpose of``// the given graph``Graph Graph::getTranspose()``{``    ``Graph g(V);``    ``for` `(``int` `v = 0; v < V; v++) {``        ``// Recur for all the vertices``        ``// adjacent to this vertex``        ``list<``int``>::iterator i;``        ``for` `(i = adj[v].begin();``             ``i != adj[v].end(); ++i) {``            ``// Add to adjacency list``            ``g.adj[*i].push_back(v);``        ``}``    ``}` `    ``// Return the reversed graph``    ``return` `g;``}` `// Function to add an Edge to the given``// graph``void` `Graph::addEdge(``int` `v, ``int` `w)``{``    ``// Add w to vâ€™s list``    ``adj[v].push_back(w);``}` `// Function that fills stack with vertices``// in increasing order of finishing times``void` `Graph::fillOrder(``int` `v, ``bool` `visited[],``                      ``stack<``int``>& Stack)``{``    ``// Mark the current node as``    ``// visited and print it``    ``visited[v] = ``true``;` `    ``// Recur for all the vertices``    ``// adjacent to this vertex``    ``list<``int``>::iterator i;` `    ``for` `(i = adj[v].begin();``         ``i != adj[v].end(); ++i) {` `        ``// If child node *i is unvisited``        ``if` `(!visited[*i]) {``            ``fillOrder(*i, visited, Stack);``        ``}``    ``}` `    ``// All vertices reachable from v``    ``// are processed by now, push v``    ``Stack.push(v);``}` `// Function that finds and prints all``// strongly connected components``void` `Graph::printSCCs()``{``    ``stack<``int``> Stack;` `    ``// Mark all the vertices as``    ``// not visited (For first DFS)``    ``bool``* visited = ``new` `bool``[V];``    ``for` `(``int` `i = 0; i < V; i++)``        ``visited[i] = ``false``;` `    ``// Fill vertices in stack according``    ``// to their finishing times``    ``for` `(``int` `i = 0; i < V; i++)``        ``if` `(visited[i] == ``false``)``            ``fillOrder(i, visited, Stack);` `    ``// Create a reversed graph``    ``Graph gr = getTranspose();` `    ``// Mark all the vertices as not``    ``// visited (For second DFS)``    ``for` `(``int` `i = 0; i < V; i++)``        ``visited[i] = ``false``;` `    ``// Now process all vertices in``    ``// order defined by Stack``    ``while` `(Stack.empty() == ``false``) {` `        ``// Pop a vertex from stack``        ``int` `v = Stack.top();``        ``Stack.pop();` `        ``// Print SCC of the popped vertex``        ``if` `(visited[v] == ``false``) {``            ``gr.DFSUtil(v, visited);``            ``cout << endl;``        ``}``    ``}``}` `// Driver Code``int` `main()``{``    ``// Given Graph``    ``Graph g(5);``    ``g.addEdge(1, 0);``    ``g.addEdge(0, 2);``    ``g.addEdge(2, 1);``    ``g.addEdge(0, 3);``    ``g.addEdge(3, 4);` `    ``// Function Call to find the SCC``    ``// using Kosaraju's Algorithm``    ``g.printSCCs();` `    ``return` `0;``}`

## Java

 `//Code in Java for the above approach``import` `java.util.*;` `class` `Graph {``    ``private` `int` `V; ``// Number of vertices in the graph``    ``private` `LinkedList[] adj; ``// Array of adjacency lists` `    ``Graph(``int` `V) {``        ``this``.V = V;``        ``adj = ``new` `LinkedList[V]; ``// Initialize adjacency lists for each vertex``        ``for` `(``int` `i = ``0``; i < V; i++) {``            ``adj[i] = ``new` `LinkedList<>(); ``// Create a new linked list for each vertex``        ``}``    ``}` `    ``// Function to add an edge from vertex v to vertex w``    ``void` `addEdge(``int` `v, ``int` `w) {``        ``adj[v].add(w); ``// Add w to the adjacency list of v``    ``}` `    ``// Recursive utility function for Depth First Search (DFS)``    ``void` `DFSUtil(``int` `v, ``boolean``[] visited) {``        ``visited[v] = ``true``; ``// Mark the current vertex as visited``        ``System.out.print(v + ``" "``); ``// Print the current vertex` `        ``// Iterate through adjacent vertices and perform DFS if not visited``        ``for` `(Integer i : adj[v]) {``            ``if` `(!visited[i]) {``                ``DFSUtil(i, visited);``            ``}``        ``}``    ``}` `    ``// Function to get the transpose (reverse) of the current graph``    ``Graph getTranspose() {``        ``Graph g = ``new` `Graph(V); ``// Create a new graph with the same number of vertices``        ``for` `(``int` `v = ``0``; v < V; v++) {``            ``// Traverse the adjacency list of each vertex and add reverse edges``            ``for` `(Integer i : adj[v]) {``                ``g.adj[i].add(v); ``// Add edge from i to v in the new graph``            ``}``        ``}``        ``return` `g; ``// Return the reversed graph``    ``}` `    ``// Function to fill the stack with vertices in order of finishing times``    ``void` `fillOrder(``int` `v, ``boolean``[] visited, Stack stack) {``        ``visited[v] = ``true``; ``// Mark the current vertex as visited` `        ``// Iterate through adjacent vertices and perform DFS if not visited``        ``for` `(Integer i : adj[v]) {``            ``if` `(!visited[i]) {``                ``fillOrder(i, visited, stack);``            ``}``        ``}` `        ``stack.push(v); ``// Push the vertex onto the stack after its DFS is complete``    ``}` `    ``// Function to print strongly connected components using Kosaraju's Algorithm``    ``void` `printSCCs() {``        ``Stack stack = ``new` `Stack<>(); ``// Stack to store vertices in order of finishing times``        ``boolean``[] visited = ``new` `boolean``[V]; ``// Array to track visited vertices` `        ``// Fill the stack with vertices in order of finishing times``        ``for` `(``int` `i = ``0``; i < V; i++) {``            ``if` `(!visited[i]) {``                ``fillOrder(i, visited, stack);``            ``}``        ``}` `        ``Graph gr = getTranspose(); ``// Get the transpose (reverse) graph` `        ``Arrays.fill(visited, ``false``); ``// Reset the visited array for the reversed graph` `        ``// Process vertices in the stack and print the strongly connected components``        ``while` `(!stack.isEmpty()) {``            ``int` `v = stack.pop(); ``// Pop a vertex from the stack` `            ``if` `(!visited[v]) {``                ``gr.DFSUtil(v, visited); ``// Perform DFS on the reversed graph``                ``System.out.println(); ``// Print a new line after each component``            ``}``        ``}``    ``}``}` `class` `Main {``    ``public` `static` `void` `main(String[] args) {``        ``Graph g = ``new` `Graph(``5``); ``// Create a graph with 5 vertices``        ``g.addEdge(``1``, ``0``);``        ``g.addEdge(``0``, ``2``);``        ``g.addEdge(``2``, ``1``);``        ``g.addEdge(``0``, ``3``);``        ``g.addEdge(``3``, ``4``);` `        ``g.printSCCs(); ``// Print strongly connected components``    ``}``}`

## Python3

 `# Python program to print the SCC of the``# graph using Kosaraju's Algorithm` `# Class to represent a graph``class` `Graph:``    ``def` `__init__(``self``,vertices):``        ``self``.V ``=` `vertices ``# No. of vertices``        ``self``.adj ``=` `[[] ``for` `i ``in` `range``(vertices)] ``# adjacency list` `    ``# Function to add an edge to graph``    ``def` `addEdge(``self``,u,v):``        ``self``.adj[u].append(v)` `    ``# A function used by DFS``    ``def` `DFSUtil(``self``,v,visited):``        ``# Mark the current node as visited``        ``# and print it``        ``visited[v] ``=` `True``        ``print``(v, end ``=` `' '``)` `        ``# Recur for all the vertices adjacent``        ``# to this vertex``        ``for` `i ``in` `self``.adj[v]:``            ``if` `visited[i] ``=``=` `False``:``                ``self``.DFSUtil(i,visited)` `    ``# Function to get transpose of graph``    ``def` `getTranspose(``self``):``        ``g ``=` `Graph(``self``.V)` `        ``# Recur for all the vertices adjacent``        ``# to this vertex``        ``for` `v ``in` `range``(``self``.V):``            ``for` `i ``in` `self``.adj[v]:``                ``g.adj[i].append(v)` `        ``return` `g` `    ``# Function to fill vertices in stack``    ``# in increasing order of finishing``    ``# times``    ``def` `fillOrder(``self``,v,visited,stack):``        ``# Mark the current node as visited``        ``visited[v] ``=` `True` `        ``# Recur for all the vertices adjacent``        ``# to this vertex``        ``for` `i ``in` `self``.adj[v]:``            ``if` `visited[i] ``=``=` `False``:``                ``self``.fillOrder(i,visited,stack)` `        ``stack.append(v)` `    ``# Function to print all SCCs``    ``def` `printSCCs(``self``):``        ``# Create a stack to store vertices``        ``stack ``=` `[]` `        ``# Mark all the vertices as not visited``        ``# (For first DFS)``        ``visited ``=` `[``False``]``*``(``self``.V)` `        ``# Fill vertices in stack according to``        ``# their finishing times``        ``for` `i ``in` `range``(``self``.V):``            ``if` `visited[i] ``=``=` `False``:``                ``self``.fillOrder(i,visited,stack)` `        ``# Create a reversed graph``        ``gr ``=` `self``.getTranspose()` `        ``# Mark all the vertices as not visited``        ``# (For second DFS)``        ``visited ``=` `[``False``]``*``(``self``.V)` `        ``# Now process all vertices in order``        ``# defined by Stack``        ``while` `stack:``            ``i ``=` `stack.pop()``            ``if` `visited[i] ``=``=` `False``:``                ``gr.DFSUtil(i,visited)``                ``print``()` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``# Given graph``    ``g ``=` `Graph(``5``)``    ``g.addEdge(``1``, ``0``)``    ``g.addEdge(``0``, ``2``)``    ``g.addEdge(``2``, ``1``)``    ``g.addEdge(``0``, ``3``)``    ``g.addEdge(``3``, ``4``)` `    ``# Function Call to find the SCC``    ``# using Kosaraju's Algorithm``    ``g.printSCCs()`

## C#

 `using` `System;``using` `System.Collections.Generic;``using` `System.Linq;` `class` `Graph``{``    ``private` `int` `V; ``// Number of vertices in the graph``    ``private` `List<``int``>[] adj; ``// Array of adjacency lists` `    ``public` `Graph(``int` `V)``    ``{``        ``this``.V = V;``        ``adj = ``new` `List<``int``>[V]; ``// Initialize adjacency lists for each vertex``        ``for` `(``int` `i = 0; i < V; i++)``        ``{``            ``adj[i] = ``new` `List<``int``>(); ``// Create a new list for each vertex``        ``}``    ``}` `    ``// Function to add an edge from vertex v to vertex w``    ``public` `void` `AddEdge(``int` `v, ``int` `w)``    ``{``        ``adj[v].Add(w); ``// Add w to the adjacency list of v``    ``}` `    ``// Recursive utility function for Depth First Search (DFS)``    ``private` `void` `DFSUtil(``int` `v, ``bool``[] visited)``    ``{``        ``visited[v] = ``true``; ``// Mark the current vertex as visited``        ``Console.Write(v + ``" "``); ``// Print the current vertex` `        ``// Iterate through adjacent vertices and perform DFS if not visited``        ``foreach` `(``int` `i ``in` `adj[v])``        ``{``            ``if` `(!visited[i])``            ``{``                ``DFSUtil(i, visited);``            ``}``        ``}``    ``}` `    ``// Function to get the transpose (reverse) of the current graph``    ``public` `Graph GetTranspose()``    ``{``        ``Graph g = ``new` `Graph(V); ``// Create a new graph with the same number of vertices``        ``for` `(``int` `v = 0; v < V; v++)``        ``{``            ``// Traverse the adjacency list of each vertex and add reverse edges``            ``foreach` `(``int` `i ``in` `adj[v])``            ``{``                ``g.adj[i].Add(v); ``// Add edge from i to v in the new graph``            ``}``        ``}``        ``return` `g; ``// Return the reversed graph``    ``}` `    ``// Function to fill the stack with vertices in order of finishing times``    ``private` `void` `FillOrder(``int` `v, ``bool``[] visited, Stack<``int``> stack)``    ``{``        ``visited[v] = ``true``; ``// Mark the current vertex as visited` `        ``// Iterate through adjacent vertices and perform DFS if not visited``        ``foreach` `(``int` `i ``in` `adj[v])``        ``{``            ``if` `(!visited[i])``            ``{``                ``FillOrder(i, visited, stack);``            ``}``        ``}` `        ``stack.Push(v); ``// Push the vertex onto the stack after its DFS is complete``    ``}` `    ``// Function to print strongly connected components using Kosaraju's Algorithm``    ``public` `void` `PrintSCCs()``    ``{``        ``Stack<``int``> stack = ``new` `Stack<``int``>(); ``// Stack to store vertices in order of finishing times``        ``bool``[] visited = ``new` `bool``[V]; ``// Array to track visited vertices` `        ``// Fill the stack with vertices in order of finishing times``        ``for` `(``int` `i = 0; i < V; i++)``        ``{``            ``if` `(!visited[i])``            ``{``                ``FillOrder(i, visited, stack);``            ``}``        ``}` `        ``Graph gr = GetTranspose(); ``// Get the transpose (reverse) graph` `        ``Array.Fill(visited, ``false``); ``// Reset the visited array for the reversed graph` `        ``// Process vertices in the stack and print the strongly connected components``        ``while` `(stack.Count > 0)``        ``{``            ``int` `v = stack.Pop(); ``// Pop a vertex from the stack` `            ``if` `(!visited[v])``            ``{``                ``gr.DFSUtil(v, visited); ``// Perform DFS on the reversed graph``                ``Console.WriteLine(); ``// Print a new line after each component``            ``}``        ``}``    ``}``}` `class` `Program``{``    ``public` `static` `void` `Main()``    ``{``        ``Graph g = ``new` `Graph(5); ``// Create a graph with 5 vertices``        ``g.AddEdge(1, 0);``        ``g.AddEdge(0, 2);``        ``g.AddEdge(2, 1);``        ``g.AddEdge(0, 3);``        ``g.AddEdge(3, 4);` `        ``g.PrintSCCs(); ``// Print strongly connected components``    ``}``}`

## Javascript

 `// Javascript code for the above approach``// Class to represent a graph``class Graph {``  ``constructor(vertices) {``    ``this``.V = vertices; ``// No. of vertices``    ``this``.adj = ``new` `Array(vertices)``      ``.fill()``      ``.map(() => []); ``// adjacency list``  ``}` `  ``// Function to add an edge to graph``  ``addEdge(u, v) {``    ``this``.adj[u].push(v);``  ``}` `  ``// A function used by DFS``  ``DFSUtil(v, visited) {``    ``// Mark the current node as visited``    ``// and print it``    ``visited[v] = ``true``;``    ``console.log(v);` `    ``// Recur for all the vertices adjacent``    ``// to this vertex``    ``for` `(let i of ``this``.adj[v]) {``      ``if` `(!visited[i]) {``        ``this``.DFSUtil(i, visited);``      ``}``    ``}``  ``}` `  ``// Function to get transpose of graph``  ``getTranspose() {``    ``const g = ``new` `Graph(``this``.V);` `    ``// Recur for all the vertices adjacent``    ``// to this vertex``    ``for` `(let v = 0; v < ``this``.V; v++) {``      ``for` `(let i of ``this``.adj[v]) {``        ``g.adj[i].push(v);``      ``}``    ``}` `    ``return` `g;``  ``}` `  ``// Function to fill vertices in stack``  ``// in increasing order of finishing``  ``// times``  ``fillOrder(v, visited, stack) {``    ``// Mark the current node as visited``    ``visited[v] = ``true``;` `    ``// Recur for all the vertices adjacent``    ``// to this vertex``    ``for` `(let i of ``this``.adj[v]) {``      ``if` `(!visited[i]) {``        ``this``.fillOrder(i, visited, stack);``      ``}``    ``}` `    ``stack.push(v);``  ``}` `  ``// Function to print all SCCs``  ``printSCCs() {``    ``// Create a stack to store vertices``    ``const stack = [];` `    ``// Mark all the vertices as not visited``    ``// (For first DFS)``    ``const visited = ``new` `Array(``this``.V).fill(``false``);` `    ``// Fill vertices in stack according to``    ``// their finishing times``    ``for` `(let i = 0; i < ``this``.V; i++) {``      ``if` `(!visited[i]) {``        ``this``.fillOrder(i, visited, stack);``      ``}``    ``}` `    ``// Create a reversed graph``    ``const gr = ``this``.getTranspose();` `    ``// Mark all the vertices as not visited``    ``// (For second DFS)``    ``visited.fill(``false``);` `    ``// Now process all vertices in order``    ``// defined by Stack``    ``while` `(stack.length > 0) {``      ``const i = stack.pop();``      ``if` `(!visited[i]) {``        ``gr.DFSUtil(i, visited);``        ``console.log(``''``);``      ``}``    ``}``  ``}``}` `// Driver Code``// Given graph``const g = ``new` `Graph(5);``g.addEdge(1, 0);``g.addEdge(0, 2);``g.addEdge(2, 1);``g.addEdge(0, 3);``g.addEdge(3, 4);` `// Function Call to find the SCC``// using Kosaraju's Algorithm``g.printSCCs();`  `// This code is contributed by sdeadityasharma`

Output
```0 1 2
3
4

```

Time Complexity:
The time complexity of Tarjan’s Algorithm and Kosaraju’s Algorithm will be O(V + E), where V represents the set of vertices and E represents the set of edges of the graph. Tarjan’s algorithm has much lower constant factors w.r.t Kosaraju’s algorithm. In Kosaraju’s algorithm, the traversal of the graph is done at least 2 times, so the constant factor can be of double time. We can print the SCC in progress with Kosaraju’s algorithm as we perform the second DFS. While performing Tarjan’s Algorithm, it requires extra time to print the SCC after finding the head of the SCCs sub-tree.

Summary:
Both the methods have the same linear time complexity, but the techniques or the procedure for the SCC computations are fairly different. Tarjan’s method solely depends on the record of nodes in a DFS to partition the graph whereas Kosaraju’s method performs the two DFS (or 3 DFS if we want to leave the original graph unchanged) on the graph and is quite similar to the method for finding the topological sorting of a graph.

Previous
Next