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.
这题目就是直接照搬Tarjan算法实现就好了,Tarjan算法在《算法导论》上第22章有,但是我看了以后并没有明白Tarjan算法的过程orz,最后还是看blog看懂的,所以推荐一个讲Tarjan算法讲的很好的blog:http://blog.csdn.net/acmmmm/article/details/16361033 还有Tarjan算法实现的具体代码:http://blog.csdn.net/acmmmm/article/details/9963693 都是一个ACM大佬写的,我就是看这两个的……其实我也看了很久才看懂Tarjan算法是干啥的……毕竟上课从来不听不知道老师讲的方法是怎么样的……
当然只要理解了Tarjan算法,这题目就相当easy了。
补充:还看到一个英文的讲Tarjan的地方,讲的很全面,在geeksforgeeks上http://www.geeksforgeeks.org/tarjan-algorithm-find-strongly-connected-components/
就是打开可能会有点慢,但是不需要FQ。
直接放代码吧:
// // main.c // Strongly Connected Components // // Created by 余南龙 on 2016/12/6. // Copyright © 2016年 余南龙. All rights reserved. // int dfn[MaxVertices], low[MaxVertices], stack[MaxVertices], top, t, in_stack[MaxVertices]; int min(int a, int b){ if(a < b){ return a; } else{ return b; } } void Tarjan(Graph G, int v){ PtrToVNode node = G->Array[v]; int son, tmp; dfn[v] = low[v] = ++t; stack[++top] = v; in_stack[v] = ; while(NULL != node){ son = node->Vert; == dfn[son]){ Tarjan(G, son); low[v] = min(low[son], low[v]); } == in_stack[son]){ low[v] = min(low[v], dfn[son]); } node = node->Next; } if(dfn[v] == low[v]){ do{ tmp = stack[top--]; printf("%d ", tmp); in_stack[tmp] = ; }while(tmp != v); printf("\n"); } } void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ){ int i; ; i < MaxVertices; i++){ dfn[i] = -; low[i] = in_stack[i] = ; } top = -; t = ; ; i < G->NumOfVertices; i++){ == dfn[i]){ Tarjan(G, i); } } }