Skip to content

Commit

Permalink
Merge pull request #73 from whyadiwhy/main
Browse files Browse the repository at this point in the history
Implementation of Tarjan's Algorithm
  • Loading branch information
skully-coder committed Oct 3, 2021
2 parents be171ba + 720ede4 commit 5eb32fd
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Dynamic Programming/TarjanAlgo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Implementation of Tarjan's Algorithm

A directed graph is strongly connected if there is a path between all pairs of vertices. A strongly connected component (SCC) of a directed graph is a maximal strongly connected subgraph. For example, there are 3 SCCs in the following graph.

Tarjan Algorithm is based on following facts:
1. DFS search produces a DFS tree/forest
2. Strongly Connected Components form subtrees of the DFS tree.
3. If we can find the head of such subtrees, we can print/store all the nodes in that subtree (including head) and that will be one SCC.
4. There is no back edge from one SCC to another (There can be cross edges, but cross edges will not be used while processing the graph).
110 changes: 110 additions & 0 deletions Dynamic Programming/TarjanAlgo/Tarjan.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#include <stdio.h>
#include <stdlib.h>

#define MAX_DEGREE 5
#define MAX_NUM_VERTICES 20

struct vertices_s {
int index;
int low_link;
int in_stack;
int deg;
int adj[MAX_DEGREE]; /* < 0 if incoming edge */
} vertices[] = {
{-1, -1, 0, 3, {2, -3, 4}},
{-1, -1, 0, 2, {-1, 3}},
{-1, -1, 0, 3, {1, -2, 7}},
{-1, -1, 0, 3, {-1, -5, 6}},
{-1, -1, 0, 2, {4, -7}},
{-1, -1, 0, 3, {-4, 7, -8}},
{-1, -1, 0, 4, {-3, 5, -6, -12}},
{-1, -1, 0, 3, {6, -9, 11}},
{-1, -1, 0, 2, {8, -10}},
{-1, -1, 0, 3, {9, -11, -12}},
{-1, -1, 0, 3, {-8, 10, 12}},
{-1, -1, 0, 3, {7, 10, -11}}
};
int num_vertices = sizeof(vertices) / sizeof(vertices[0]);

struct stack_s {
int top;
int items[MAX_NUM_VERTICES];
} stack = {-1, {}};

void stack_push(int v) {
stack.top++;
if (stack.top < MAX_NUM_VERTICES)
stack.items[stack.top] = v;
else {
printf("Stack is full!\n");
exit(1);
}
}

int stack_pop() {
return stack.top < 0 ? -1 : stack.items[stack.top--];
}

#define the_vertex(X) (vertices[(X)])
#define v_index(X) (the_vertex((X)).index)
#define v_lowlink(X) (the_vertex((X)).low_link)
#define v_instack(X) (the_vertex((X)).in_stack)
#define v_deg(X) (the_vertex((X)).deg)
#define v_adj(X) (the_vertex((X)).adj)

int curr_index = 0;

void reset_vertices() {
int i;
for (i = 0; i < num_vertices; ++i) {
v_index(i) = -1;
v_lowlink(i) = -1;
v_instack(i) = 0;
}
}

int min(int a, int b) {
return a < b ? a : b;
}

void scc(int v) {
int i, c, n;
v_index(v) = curr_index;
v_lowlink(v) = curr_index;
++curr_index;

stack_push(v);
v_instack(v) = 1;

for (i = 0, c = v_deg(v); i < c; ++i)
if (v_adj(v)[i] > 0) {
n = v_adj(v)[i] - 1;
if (v_index(n) == -1) {
scc(n);
v_lowlink(v) = min(v_lowlink(v), v_lowlink(n));
} else if (v_instack(n)) {
v_lowlink(v) = min(v_lowlink(v), v_index(n));
}
}

if (v_index(v) == v_lowlink(v)) {
printf("scc: ");
while ((n = stack_pop()) != -1) {
v_instack(n) = 0;
printf("%d ", n + 1);
if (n == v) {
printf("\n");
break;
}
}
}
}

int main(void) {
int i;
reset_vertices();
for (i = 0; i < num_vertices; ++i)
if (v_index(i) == -1)
scc(i);
return 0;
}

0 comments on commit 5eb32fd

Please sign in to comment.