Strongly Connected Components
Write a program to find the strongly connected components in a digraph.
Format of functions:
void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) );
where Graph
is defined as the following:
typedef struct VNode *PtrToVNode;
struct VNode {
Vertex Vert;
PtrToVNode Next;
};
typedef struct GNode *Graph;
struct GNode {
int NumOfVertices;
int NumOfEdges;
PtrToVNode *Array;
};
Here void (*visit)(Vertex V)
is a function parameter that is passed into StronglyConnectedComponents
to handle (print with a certain format) each vertex that is visited. The function StronglyConnectedComponents
is supposed to print a return after each component is found.
Sample program of judge:
#include <stdio.h>
#include <stdlib.h>
#define MaxVertices 10 /* maximum number of vertices */
typedef int Vertex; /* vertices are numbered from 0 to MaxVertices-1 */
typedef struct VNode *PtrToVNode;
struct VNode {
Vertex Vert;
PtrToVNode Next;
};
typedef struct GNode *Graph;
struct GNode {
int NumOfVertices;
int NumOfEdges;
PtrToVNode *Array;
};
Graph ReadG(); /* details omitted */
void PrintV( Vertex V )
{
printf("%d ", V);
}
void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) );
int main()
{
Graph G = ReadG();
StronglyConnectedComponents( G, PrintV );
return 0;
}
/* Your function will be put here */
Sample Input (for the graph shown in the figure):
4 5
0 1
1 2
2 0
3 1
3 2
Sample Output:
3
1 2 0
Note: The output order does not matter. That is, a solution like
0 1 2
3
is also considered correct.
My code
注:有些注释的代码是我用来debug用的
#define min(a,b) (((a) < (b)) ? (a) : (b))
int visited[20] = {0};
int num[20] = {0}, low[20] = {0};
int cnt = 0;
int stack[21], inStack[21];// 栈从1开始
int top = 0;
void Dfs(Graph G, Vertex v, void (*visit)(Vertex V));
void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) )
{
// for (int i = 0; i < G->NumOfVertices; i++) {
// for (PtrToVNode w = G->Array[i]; w; w = w->Next) {
// printf("G->Array[%d]->Vert = %d\n", i, w->Vert);
// // printf("G->Array[%d]->Vert = %d\n", i, G->Array[i]->Vert);
// }
// // printf("\n");
// }
for (int i = 0; i < G->NumOfVertices; i++) {
if (visited[i] == 0) {
// printf("G->Array[%d]->Vert = %d\n", i, G->Array[i]->Vert);
// visit(G->Array[i]->Vert);
// printf("%d ", i);
Dfs(G, i, visit);
// printf("\n");
}
}
}
void Dfs(Graph G, Vertex v, void (*visit)(Vertex V))
{
visited[v] = 1;
// printf("num[%d] = low[%d] = %d\n", v, v, cnt);
num[v] = low[v] = cnt++;// 从0开始
stack[++top] = v;
// printf("stack[%d] = %d\n", top, v);
inStack[v] = 1;
PtrToVNode w;
for (w = G->Array[v]; w != NULL; w = w->Next) {
if (visited[w->Vert] == 0) {
Dfs(G, w->Vert, visit);
low[v] = min(low[v], low[w->Vert]);
}
else if (inStack[w->Vert]) {
low[v] = min(low[v], num[w->Vert]);
}
}
if (num[v] == low[v]) {
while (stack[top] != v) {
visit(stack[top]);
inStack[stack[top]] = 0;
top--;
}
visit(v);
inStack[v] = 0;
top--;
printf("\n");
}
}