-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy path6-10_Strongly Connected Components (30).c
70 lines (63 loc) · 1.95 KB
/
6-10_Strongly Connected Components (30).c
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
// Helper structure to store DFS information for each vertex
typedef struct {
int dfn; // Discovery time
int low; // Lowest vertex reachable
int inStack; // Whether vertex is in stack
} VertexInfo;
// Helper function for Tarjan's algorithm
void Tarjan(Graph G, Vertex v, VertexInfo *info, Vertex *stack, int *top,
int *time, void (*visit)(Vertex), int *visited) {
info[v].dfn = info[v].low = (*time)++;
stack[(*top)++] = v;
info[v].inStack = 1;
PtrToVNode node = G->Array[v];
while (node) {
Vertex w = node->Vert;
if (info[w].dfn == -1) { // Unvisited vertex
Tarjan(G, w, info, stack, top, time, visit, visited);
if (info[w].low < info[v].low)
info[v].low = info[w].low;
} else if (info[w].inStack) { // Back edge to vertex in stack
if (info[w].dfn < info[v].low)
info[v].low = info[w].dfn;
}
node = node->Next;
}
// If v is root of SCC, pop stack and print component
if (info[v].dfn == info[v].low) {
Vertex w;
do {
w = stack[--(*top)];
info[w].inStack = 0;
if (!visited[w]) {
(*visit)(w);
visited[w] = 1;
}
} while (w != v);
printf("\n"); // Print newline after each component
}
}
void StronglyConnectedComponents(Graph G, void (*visit)(Vertex V)) {
// Initialize arrays
VertexInfo *info = (VertexInfo*)malloc(G->NumOfVertices * sizeof(VertexInfo));
Vertex *stack = (Vertex*)malloc(G->NumOfVertices * sizeof(Vertex));
int *visited = (int*)calloc(G->NumOfVertices, sizeof(int));
int top = 0; // Stack top
int time = 0; // DFS timestamp
// Initialize vertex info
for (Vertex v = 0; v < G->NumOfVertices; v++) {
info[v].dfn = -1;
info[v].low = -1;
info[v].inStack = 0;
}
// Run Tarjan's algorithm for each unvisited vertex
for (Vertex v = 0; v < G->NumOfVertices; v++) {
if (info[v].dfn == -1) {
Tarjan(G, v, info, stack, &top, &time, visit, visited);
}
}
// Free memory
free(info);
free(stack);
free(visited);
}