|
| 1 | +// A directed graph is strongly connected if |
| 2 | +// there is a path between all pairs of vertices. |
| 3 | +// A strongly connected component (SCC) of a directed graph |
| 4 | +// is a maximal strongly connected subgraph. |
| 5 | +#include<bits/stdc++.h> |
| 6 | +using namespace std; |
| 7 | + |
| 8 | +class Graph{ |
| 9 | + public: |
| 10 | + int V; |
| 11 | + list<int> *adj; |
| 12 | + Graph(int V); |
| 13 | + void addEdge(int u,int v); |
| 14 | + void fillFinishtime(int v,bool visited[],stack<int>&Stack); |
| 15 | + void DFSUtil(int v,bool visited[]); |
| 16 | + void printSCCs(); |
| 17 | + Graph getTranspose(); |
| 18 | +}; |
| 19 | + |
| 20 | +Graph Graph::getTranspose(){ |
| 21 | + Graph trans(V); |
| 22 | + for(int v=0;v<V;v++){ |
| 23 | + list<int>::iterator i; |
| 24 | + for(i=adj[v].begin();i!=adj[v].end();++i){ |
| 25 | + trans.adj[*i].push_back(v); |
| 26 | + } |
| 27 | + } |
| 28 | + return trans; |
| 29 | +} |
| 30 | + |
| 31 | +void Graph::DFSUtil(int v, bool visited[]) |
| 32 | +{ |
| 33 | + // Mark the current node as visited and print it |
| 34 | + visited[v] = true; |
| 35 | + cout << v << " "; |
| 36 | + |
| 37 | + // Recur for all the vertices adjacent to this vertex |
| 38 | + list<int>::iterator i; |
| 39 | + for (i = adj[v].begin(); i != adj[v].end(); ++i) |
| 40 | + if (!visited[*i]) |
| 41 | + DFSUtil(*i, visited); |
| 42 | +} |
| 43 | + |
| 44 | + |
| 45 | +void Graph::fillFinishtime(int v,bool visited[],stack<int>&Stack){ |
| 46 | + visited[v] = true; |
| 47 | + list<int> ::iterator it; |
| 48 | + for(it = adj[v].begin();it!=adj[v].end();++it) |
| 49 | + if(!visited[*it]) |
| 50 | + fillFinishtime(*it,visited,Stack); |
| 51 | + Stack.push(v); |
| 52 | +} |
| 53 | + |
| 54 | +void Graph:: printSCCs(){ |
| 55 | + stack<int>Stack; |
| 56 | + bool *visited = new bool[V]; |
| 57 | + for(int i=0;i<V;i++) |
| 58 | + visited[i] = false; |
| 59 | + //fill vertices in stack accd to their finish times |
| 60 | + for(int i=0;i<V;i++) |
| 61 | + if(!visited[i]) |
| 62 | + fillFinishtime(i,visited,Stack); |
| 63 | + //create reversed graph |
| 64 | + // cout<<"stack is \n"; |
| 65 | + // cout<<"size of the stack is "<<Stack.size()<<endl; |
| 66 | + // while(!Stack.empty()) |
| 67 | + // {cout<<Stack.top()<<endl;Stack.pop();} |
| 68 | + // cout<<endl; |
| 69 | + Graph reversed = getTranspose(); |
| 70 | + // marke all unvisited for 2nd dfs |
| 71 | + for(int i=0;i<V;i++) |
| 72 | + visited[i] = false; |
| 73 | + while(!Stack.empty()){ |
| 74 | + int v = Stack.top(); |
| 75 | + Stack.pop(); |
| 76 | + if(!visited[v]){ |
| 77 | + reversed.DFSUtil(v,visited); |
| 78 | + cout<<endl; |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | +} |
| 83 | + |
| 84 | + |
| 85 | +void Graph::addEdge(int u, int v){ |
| 86 | + adj[u].push_back(v); |
| 87 | +} |
| 88 | +Graph::Graph(int v){ |
| 89 | + this->V = v; |
| 90 | + adj = new list<int>[V]; |
| 91 | +} |
| 92 | + |
| 93 | + |
| 94 | +int main(){ |
| 95 | + Graph g(5); g.addEdge(0, 2); |
| 96 | + g.addEdge(1, 0); |
| 97 | + |
| 98 | + g.addEdge(2, 1); |
| 99 | + g.addEdge(0, 3); |
| 100 | + g.addEdge(3, 4); |
| 101 | + |
| 102 | + cout << "Following are strongly connected components in " |
| 103 | + "given graph \n"; |
| 104 | + g.printSCCs(); |
| 105 | + |
| 106 | + return 0; |
| 107 | + |
| 108 | +} |
0 commit comments