I am trying to implement Kosaraju's Strongly connected components algorithm using recursive approach in C++. While the program runs fine on small graphs but terminates in-between execution while running node-ranking step of the algorithm on large graphs having 875714 nodes.
The function that causes the problem is : Graph::fillOrder(int v, bool visited[], stack &Stack)
File link : File link: https://drive.google.com/file/d/1aL19d6FCTT9vW70jBGyH-r7MpOOQ7gyz/view?usp=sharing
I went through the net to search for a possible solution to it but couldn't find one. While there are few non-recursive approaches suggesting that recursive approaches hit stack overflow problem, I want to know if that's the case is there any way to solve it ?
#include<iostream>
#include<list>
#include<stack>
#include<fstream>
using namespace std;
class Graph{
int V;
list<int> *adj;
void fillOrder(int v, bool visited[], stack<int> &stack);
void DFSUtil(int v, bool visited[], int &count);
public:
Graph(int V);
void addEdge(int v, int w);
void printSCCs();
Graph getTranspose();
};
Graph::Graph(int V){
this->V = V;
adj = new list<int>[V];
}
void Graph::DFSUtil(int v, bool visited[], int &count){
visited[v] = true;
count++;
list<int>::iterator it;
for(it = adj[v].begin(); it!=adj[v].end(); it++){
if(!visited[*it])
DFSUtil(*it, visited, count);
}
}
Graph Graph::getTranspose(){
Graph g(V);
for(int v=0; v<V; v++){
list<int>::iterator it;
for(it=adj[v].begin(); it!=adj[v].end(); it++){
g.adj[*it].push_back(v);
}
}
return g;
}
//add edge to graph
void Graph::addEdge(int v, int w){
adj[v].push_back(w);
}
//node ranking function
void Graph::fillOrder(int v, bool visited[], stack<int> &Stack){
visited[v] = true;
list<int> :: iterator it;
for(it=adj[v].begin(); it!=adj[v].end(); it++){
if(!visited[*it])
fillOrder(*it, visited, Stack);
}
Stack.push(v);
}
//print SCCs
void Graph::printSCCs(){
stack<int> Stack;
//keeping track of nodes visited
bool *visited = new bool[V];
for(int i=0; i<V; i++){
visited[i]=false;
}
//node ranking
for(int i=0; i<V; i++){
cout<<i<<" ";
if(visited[i]==false){
fillOrder(i, visited, Stack);
}
}
//computing transpose of the graph
Graph gr = getTranspose();
//reseting visited values for every node to false
for(int i=0; i<V; i++){
visited[i]=false;
}
int max_count=0;
while(Stack.empty()==false){
int v = Stack.top();
Stack.pop();
if(visited[v]==false){
int count=0;
gr.DFSUtil(v, visited, count);
if(count>max_count){
max_count = count;
cout<<"\nMax count: "<<max_count;
}
}
}
}
int main()
{
Graph g(875714);
ifstream file;
file.open("SCC.txt");
int s, e;
while(file>>s>>e){
//eleminating self loops
if(s==e)
continue;
else
g.addEdge((s-1), (e-1)); //for files containing nodes from 1
}
cout << "Following are strongly connected components in "
"given graph \n";
g.printSCCs();
return 0;
}
Expected result: print size of each strongly connected component in the graph
Actual result: Termination while execution without completing the entire program