Pagini recente » Cod sursa (job #568960) | Cod sursa (job #852386) | Cod sursa (job #355628) | Cod sursa (job #632048) | Cod sursa (job #3200243)
// Strongly connected components - Tarjan's algorithm.
#include <stdio.h>
const int MAX_NODES = 100'000;
const int MAX_EDGES = 200'000;
const int SEPARATOR = 0;
struct edge {
int v, next;
};
struct node {
int adj;
int time_in;
int low;
bool on_stack;
};
node n[MAX_NODES + 1];
int st[MAX_NODES], ss; // DFS stack
edge e[MAX_EDGES + 1];
int comp[2 * MAX_NODES], comp_ptr, num_comps;
int num_nodes, time;
void read_graph() {
FILE* f = fopen("ctc.in", "r");
int num_edges, u, v;
fscanf(f, "%d %d", &num_nodes, &num_edges);
for (int i = 1; i <= num_edges; i++) {
fscanf(f, "%d %d", &u, &v);
e[i] = { v, n[u].adj };
n[u].adj = i;
}
fclose(f);
}
int min(int x, int y) {
return (x < y) ? x : y;
}
void pop_scc(int last) {
int v;
do {
v = st[--ss];
n[v].on_stack = false;
comp[comp_ptr++] = v;
} while (v != last);
comp[comp_ptr++] = SEPARATOR;
num_comps++;
}
void dfs(int u) {
n[u].time_in = n[u].low = ++time;
n[u].on_stack = true;
st[ss++] = u;
for (int ptr = n[u].adj; ptr; ptr = e[ptr].next) {
int v = e[ptr].v;
if (!n[v].time_in) {
// Traverse the white descendant and make a note of how high it can
// climb.
dfs(v);
n[u].low = min(n[u].low, n[v].low);
} else if (n[v].on_stack) {
// We can climb to v's level.
n[u].low = min(n[u].low, n[v].time_in);
}
}
// If no vertex from u's subtree can climb higher than u, then the stack
// from u to the top is a SCC.
if (n[u].low == n[u].time_in) {
pop_scc(u);
}
}
void dfs_driver() {
for (int u = 1; u <= num_nodes; u++) {
if (!n[u].time_in) {
dfs(u);
}
}
}
void write_components() {
FILE* f = fopen("ctc.out", "w");
fprintf(f, "%d\n", num_comps);
for (int i = 0; i < comp_ptr; i++) {
if (comp[i] == SEPARATOR) {
fprintf(f, "\n");
} else {
fprintf(f, "%d ", comp[i]);
}
}
fclose(f);
}
int main() {
read_graph();
dfs_driver();
write_components();
return 0;
}