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 intoStronglyConnectedComponents
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.
利用TARJAN算法
int Instack[MaxVertices];
int stack[MaxVertices];
int Num[MaxVertices];
int Low[MaxVertices];
int print[MaxVertices];
int counter=0;
int j=-1;
int m=0;
void tarjan(Graph G,void(*visit)(Vertex V),int v);
void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) )
{
int i=0;
for(i=0;i<G->NumOfVertices;i++){
if(Num[i]<=0)
tarjan(G,visit,i);
}
}
void tarjan(Graph G,void(*visit)(Vertex V),int v)
{
PtrToVNode W;
int w,p;
Low[v]=Num[v]=++counter;
Instack[v]=1;
stack[++j]=v;
for(W=G->Array[v];W!=NULL;W=W->Next){
w=W->Vert;
if(Num[w]<=0){
tarjan(G,visit,w);
Low[v]=Low[v]<Low[w]?Low[v]:Low[w];
}
else if(Instack[w]==1&&Num[w]<Low[v]){
Low[v]=Num[w];
}
}
if(Num[v]==Low[v]){
do{
p=stack[j--];
print[m++]=p;
Instack[p]=0;
}while(p!=v);
for(m=m-1;m>=0;m--){
(*visit)(print[m]);
}
printf("\n");
m=0;
}
}