@@ -73,23 +73,20 @@ Finally, it is appropriate to mention [topological sort](topological-sort.md) he
73
73
74
74
## Implementation
75
75
``` cpp
76
- vector<vector<int >> adj, adj_rev; // Adjacency lists of G and G^T.
77
- vector<bool > visited; // Keeps track of which nodes are already visited.
78
- vector<int > order; // Sorted list of vertices in G by exit time.
79
- vector<int > component; // Stores one strongly connected component at a time.
76
+ vector<vector<int >> adj, adj_rev; // adjacency lists of G and G^T
77
+ vector<bool > visited; // keeps track of which nodes are already visited
78
+ vector<int > order; // sorted list of G's vertices by exit time
79
+ vector<int > component; // stores one strongly connected component at a time
80
80
81
- // Depth first search on G, used in step 1 of the algorithm.
82
81
void dfs1 (int v) {
83
82
visited[ v] = true;
84
-
85
83
for (auto u : adj[ v] )
86
84
if (!visited[ u] )
87
85
dfs1(u);
88
86
89
87
order.push_back(v);
90
88
}
91
89
92
- // Depth first search on G^T, used in step 2 of the algorithm.
93
90
void dfs2(int v) {
94
91
visited[ v] = true;
95
92
component.push_back(v);
@@ -100,60 +97,47 @@ void dfs2(int v) {
100
97
}
101
98
102
99
int main() {
103
- int n = ...; // Number of vertices in G.
104
-
105
- // Add edges to G.
106
- for (int i=0; i < n; i++) {
100
+ int n = ...;
101
+ for ( ... ) {
107
102
int a = ..., b = ...;
108
103
adj[ a] .push_back(b);
109
104
adj_rev[ b] .push_back(a);
110
105
}
111
106
112
107
visited.assign(n, false);
113
108
114
- // Run the first series of depth first searches.
109
+ // first series of depth first searches
115
110
for (int i = 0; i < n; i++)
116
111
if (!visited[i])
117
112
dfs1(i);
118
113
119
114
visited.assign(n, false);
120
115
reverse(order.begin(), order.end());
121
116
122
- // These vectors are for the condensation graph;
123
- // they are explained in the text below.
124
- vector<int> roots(n, 0);
117
+ // condensation graph (explained in text below)
125
118
vector<int> root_nodes;
119
+ vector<int> roots(n, 0);
126
120
vector<vector<int>> adj_scc(n);
127
121
128
- // Run the second series of depth first searches,
129
- // and add vertices to condensation graph.
130
- // During this process, we find all strongly connected components.
122
+ // second series of depth first searches
131
123
for (auto v : order)
132
124
if (!visited[v]) {
133
125
dfs2(v);
134
-
135
- // Found a strongly connected component!
136
- // Add it to the condensation graph...
137
126
int root = component.front();
138
127
for (auto u : component) roots[u] = root;
139
128
root_nodes.push_back(root);
140
-
141
129
component.clear();
142
130
}
143
131
144
132
145
- // Add edges to condensation graph.
133
+ // add edges to condensation graph
146
134
for (int v = 0; v < n; v++)
147
- for (auto u : adj[v]) {
148
- int root_v = roots[v],
149
- root_u = roots[u];
150
-
151
- if (root_u != root_v)
152
- adj_scc[root_v].push_back(root_u);
153
- }
135
+ for (auto u : adj[v])
136
+ if (roots[v] != roots[u])
137
+ adj_scc[roots[v]].push_back(roots[u]);
154
138
155
- // At this point, we found all strongly connected
156
- // components and constructed the condensation graph .
139
+ // finished finding SCCs and constructing condensation graph.
140
+ ...... .
157
141
}
158
142
```
159
143
0 commit comments