-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStrongly Connected Component.cpp
67 lines (67 loc) · 1.68 KB
/
Strongly Connected Component.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
/**first step
for(int i=1;i<=n;i++)
if(vis[i]==WHITE)SCC(i);
2nd step:shrink(n);*/
#define WHITE 0
#define GRAY 1
#define BLACK 2
int disc[N], low[N];
vector<int>adj[N],adj_shrink[N], node[N];
int vis[N],head=1;
int globalCnt = 0;
int flagCycle;
vector<int> tarjan;
int cycle[N],color[N];
void init(int n){
globalCnt=0;
flagCycle=false;
head=1;tarjan.clear();
for(int i=0;i<=n;i++){
adj[i].clear();adj_shrink[i].clear();
}
CLR(vis);CLR(color);
CLR(low);CLR(disc);CLR(cycle);
}
int SCC ( int s ) {
vis[s] = GRAY;
disc[s] = low[s] = globalCnt++;
tarjan.push_back(s);
for ( int i = 0; i < adj[s].size(); i++ ) {
int t = adj[s][i];
if ( vis[t] == WHITE ) { ///This is tree edge
SCC ( t );
low[s] = min ( low[s], low[t] );
}
else if ( vis[t] == GRAY ) { ///This is back edge
///Cycle detected
flagCycle = true;
low[s] = min ( low[s], low[t] );
}
}
if ( disc[s] == low[s] ) {
while ( 1 ) {
int lastNode = tarjan.back();
cycle[lastNode] = head;
node[head].pb(lastNode);
tarjan.pop_back();
vis[lastNode] = BLACK;
if ( lastNode == s ) break;
}
head++;
}
}
void dfs(int src){
if(color[src])return;
color[src]=1;
for(int i=0;i<adj[src].size();i++){
if(cycle[src]!=cycle[adj[src][i]]){
adj_shrink[cycle[src]].pb(cycle[adj[src][i]]);
dfs(adj[src][i]);
}
}
}
void shrink(int n){
for(int i=1;i<=n;i++){
if(color[i]==0)dfs(i);
}
}