-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathstrong.c
138 lines (102 loc) · 3.02 KB
/
strong.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
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
/* strong.c
Identify strongly connected components in a graph
by: Steven Skiena
begun: March 27, 2002
*/
/*
Copyright 2003 by Steven S. Skiena; all rights reserved.
Permission is granted for use in non-commerical applications
provided this copyright notice remains intact and unchanged.
This program appears in my book:
"Programming Challenges: The Programming Contest Training Manual"
by Steven Skiena and Miguel Revilla, Springer-Verlag, New York 2003.
See our website www.programming-challenges.com for additional information.
This book can be ordered from Amazon.com at
http://www.amazon.com/exec/obidos/ASIN/0387001638/thealgorithmrepo/
*/
#include <stdio.h>
#include "bool.h"
#include "bfs-dfs.h"
#include "stack.h"
extern bool processed[]; /* which vertices have been processed */
extern bool discovered[]; /* which vertices have been found */
extern int parent[]; /* discovery relation */
extern int entry_time[]; /* time of vertex entry */
extern int exit_time[]; /* time of vertex exit */
/* [[[ sc_arrays_cut */
int low[MAXV+1]; /* oldest vertex surely in component of v */
int scc[MAXV+1]; /* strong component number for each vertex */
/* ]]] */
stack active; /* active vertices of unassigned component */
int components_found; /* number of strong components identified */
/* [[[ pvearly_strong_cut */
void process_vertex_early(int v) {
push(&active, v);
}
/* ]]] */
/* [[[ pop_comp_strong_cut */
void pop_component(int v) {
int t; /* vertex placeholder */
components_found = components_found + 1;
printf("%d is in component %d \n", v, components_found);
scc[v] = components_found;
while ((t = pop(&active)) != v) {
scc[t] = components_found;
printf("%d is in component %d with %d \n", t, components_found, v);
}
}
/* ]]] */
/* [[[ pvlate_strong_cut */
void process_vertex_late(int v) {
if (low[v] == v) {
pop_component(v);
}
if (entry_time[low[v]] < entry_time[low[parent[v]]]) {
low[parent[v]] = low[v];
}
}
/* ]]] */
/* [[[ pedge_strong_cut */
void process_edge(int x, int y) {
int class; /* edge class */
class = edge_classification(x, y);
if (class == BACK) {
if (entry_time[y] < entry_time[low[x]]) {
low[x] = y;
}
}
if (class == CROSS) {
if (scc[y] == -1) { /* component not yet assigned */
if (entry_time[y] < entry_time[ low[x]]) {
low[x] = y;
}
}
}
}
/* ]]] */
/* [[[ strong_comp_cut */
void strong_components(graph *g) {
int i; /* counter */
for (i = 1; i <= (g->nvertices); i++) {
low[i] = i;
scc[i] = -1;
}
components_found = 0;
init_stack(&active);
initialize_search(g);
for (i = 1; i <= (g->nvertices); i++) {
if (discovered[i] == FALSE) {
dfs(g, i);
}
}
}
/* ]]] */
int main(void)
{
graph g;
int i;
read_graph(&g, TRUE);
print_graph(&g);
strong_components(&g);
return 0;
}