6-10 Strongly Connected Components (30point(s))
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.
Example:
Vertex aux1[MaxVertices];
int top1 = -1;
Vertex aux2[MaxVertices];
int top2 = -1;
int detect[MaxVertices];
int connected[MaxVertices];
int time = 0;
void Gabow( Graph G, Vertex v, void (*visit)(Vertex V) )
{
PtrToVNode node;
detect[v] = ++time;
aux1[++top1] = v;
aux2[++top2] = v;
node = G->Array[v];
while(node) {
Vertex adj = node->Vert;
if(!detect[adj]) {
Gabow(G, adj, visit);
} else if(!connected[adj]) {
Vertex com = aux1[top1];
while(detect[com] > detect[adj]) {
com = aux1[--top1];
}
}
node = node->Next;
}
if(aux1[top1] == v) {
top1--;
do {
visit(aux2[top2]);
connected[aux2[top2]] = 1;
} while(aux2[top2--] != v);
printf("\n");
}
}
void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) )
{
for(Vertex i = 0; i < G->NumOfVertices; i++) {
detect[i] = connected[i] = 0;
}
for(Vertex i = 0; i < G->NumOfVertices; i++) {
if(detect[i] == 0) Gabow(G, i, visit);
}
}
思路:
使用Gabow算法,生成深度优先树(强连通分量),并在深度优先树的根节点处从aux2出栈并visit强连通分量的内部结点.