-
Notifications
You must be signed in to change notification settings - Fork 0
/
Strongly_connected _pmponents.cpp
145 lines (121 loc) · 3.29 KB
/
Strongly_connected _pmponents.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//C++ Implementation of Kosaraju's algorithm to print all SCCs
//Strongly connected cpmponents
#include <iostream>
#include <list>
#include <stack>
using namespace std;
class Graph
{
int V; //No. of vertices
list<int>* adj; //An array of adjacency lists
//Fills Stack with vertices (in increasing order of finishing
//times).The top element of stack has the maximum finishing
//time
void fillOrder(int v,bool visited[],stack<int> &Stack);
//A recursive function to print DFS starting from v
void DFSUtil(int v,bool visited[]);
public:
Graph(int V);
void addEdge(int v,int w);
//The main function that finds and prints strongly connected
//components
void printSCCs();
//Function that return transpose of this graph
Graph getTranspose();
};
Graph::Graph(int V)
{
this->V=V;
adj=new list<int>[V];
}
// A 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;
for(i=adj[v].begin();i!=adj[v].end();i++)
{
if(!visited[*i])
DFSUtil(*i,visited);
}
}
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++)
{
g.adj[*i].push_back(v);
}
}
return g;
}
void Graph::addEdge(int v,int w)
{
adj[v].push_back(w);
}
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(!visited[*i])
fillOrder(*i,visited,Stack);
//All vertices reachable from v are processed by now,push v
Stack.push(v);
}
//The main function that finds and prints 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 Strongly connected component of the poped vertex
if(visited[v]==false)
{
gr.DFSUtil(v,visited);
cout<<endl;
}
}
}
// Driver program to test above functions
int main()
{
// Create a graph given in the above diagram
Graph g(5);
g.addEdge(1, 0);
g.addEdge(0, 2);
g.addEdge(2, 1);
g.addEdge(0, 3);
g.addEdge(3, 4);
cout << "Following are strongly connected components in "
"given graph \n";
g.printSCCs();
return 0;
}