|
1 | 1 | #include <bits/stdc++.h>
|
2 | 2 | using namespace std;
|
3 | 3 |
|
4 |
| -unordered_map<int,vector<int>> graph; |
5 |
| -unordered_map<int,vector<int>> rgraph; |
6 |
| -unordered_set<int> visited; |
7 |
| -stack<int> topdown; |
8 |
| -unordered_map<int,int> represent; |
9 |
| -int numSCC = 0; |
10 |
| -int n; |
11 |
| - |
12 |
| -void dfs1(int idx) { |
13 |
| - if(visited.count(idx)) return; |
14 |
| - visited.insert(idx); |
15 |
| - for(int next : graph[idx]) |
16 |
| - dfs1(next); |
17 |
| - topdown.push(idx); |
18 |
| -} |
| 4 | +struct Kosaraju { |
| 5 | + vector<vector<int>> graph, rgraph; |
| 6 | + vector<int> represent; |
| 7 | + vector<bool> visited; |
| 8 | + stack<int> topdown; |
| 9 | + int numSCC; |
| 10 | + int n; |
19 | 11 |
|
20 |
| -void dfs2(int idx, int rep) { |
21 |
| - if(visited.count(idx)) return; |
22 |
| - visited.insert(idx); |
23 |
| - represent[idx] = rep; |
24 |
| - for(int next : rgraph[idx]) |
25 |
| - dfs2(next, rep); |
26 |
| -} |
| 12 | + Kosaraju(int N): n(N) { |
| 13 | + graph = rgraph = vector<vector<int>>(n); |
| 14 | + } |
27 | 15 |
|
28 |
| -void kosaraju() { |
29 |
| - // step1: do dfs on normal graph to get stack topdown ordering |
30 |
| - for(int i=0;i<n;i++) { |
31 |
| - dfs1(i); |
| 16 | + void dfs1(int idx) { |
| 17 | + if(visited[idx]) return; |
| 18 | + visited[idx] = true; |
| 19 | + for(int next : graph[idx]) dfs1(next); |
| 20 | + topdown.push(idx); |
32 | 21 | }
|
33 |
| - visited.clear(); |
34 |
| - // step2: find representative for each node using reverse graph and topdown stack |
35 |
| - while(!topdown.empty()) { |
36 |
| - int cur = topdown.top(); topdown.pop(); |
37 |
| - if(visited.count(cur)) continue; |
38 |
| - dfs2(cur, cur); |
39 |
| - numSCC++; |
| 22 | + |
| 23 | + void dfs2(int idx, int rep) { |
| 24 | + if(visited[idx]) return; |
| 25 | + visited[idx] = true; |
| 26 | + represent[idx] = rep; |
| 27 | + for(int next : rgraph[idx]) dfs2(next, rep); |
40 | 28 | }
|
41 |
| -} |
42 | 29 |
|
43 |
| -void constructGraph(vector<vector<int>>& edges, int s) { |
44 |
| - n = s; |
45 |
| - for(auto edge : edges) { |
46 |
| - graph[edge[0]].push_back(edge[1]); |
47 |
| - rgraph[edge[1]].push_back(edge[0]); |
| 30 | + int start() { |
| 31 | + numSCC = 0; |
| 32 | + represent = vector<int>(n); |
| 33 | + visited = vector<bool>(n); |
| 34 | + // step1: do dfs on normal graph to get stack topdown ordering |
| 35 | + for(int i=0;i<n;i++) dfs1(i); |
| 36 | + |
| 37 | + // step2: find representative for each node using reverse graph and topdown stack |
| 38 | + visited.assign(n, false); |
| 39 | + while(!topdown.empty()) { |
| 40 | + int cur = topdown.top(); topdown.pop(); |
| 41 | + if(visited[cur]) continue; |
| 42 | + dfs2(cur, cur); |
| 43 | + numSCC++; |
| 44 | + } |
| 45 | + return numSCC; |
48 | 46 | }
|
49 |
| -} |
| 47 | + |
| 48 | + void addEdge(int a, int b) { |
| 49 | + graph[a].push_back(b); |
| 50 | + rgraph[b].push_back(a); |
| 51 | + } |
| 52 | +}; |
50 | 53 |
|
51 | 54 | int main() {
|
52 | 55 | // expect 3 SCC from this graph
|
| 56 | + Kosaraju ko(6); |
53 | 57 | vector<vector<int>> edges = {{0,1},{1,2},{2,4},{4,5},{5,4},{3,1},{2,3}};
|
54 |
| - constructGraph(edges, 6); |
55 |
| - kosaraju(); |
56 |
| - printf("Number of SCC: %d\n", numSCC); |
57 |
| - for(auto p : represent) { |
58 |
| - printf("Node %d, representative node %d\n", p.first, p.second); |
| 58 | + for(auto& edge : edges) ko.addEdge(edge[0], edge[1]); |
| 59 | + |
| 60 | + ko.start(); |
| 61 | + printf("Number of SCC: %d\n", ko.numSCC); |
| 62 | + for(int i=0; i<ko.n; i++) { |
| 63 | + printf("Node %d, representative node %d\n", i, ko.represent[i]); |
59 | 64 | }
|
60 | 65 | }
|
0 commit comments