首页 > 代码库 > PTA Strongly Connected Components

PTA 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.

这题目就是直接照搬Tarjan算法实现就好了,一个讲Tarjan算法讲的很好的blog:http://blog.csdn.net/acmmmm/article/details/16361033 还有Tarjan算法实现的具体代码:http://blog.csdn.net/acmmmm/article/details/9963693 都是一个ACM大佬写的,其实我也看了很久才看懂Tarjan算法是干啥的……毕竟上课从来不听不知道老师讲的方法是怎么样的……

直接放代码吧:

//
//  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] = 1;
    
    while(NULL != node){
        son = node->Vert;
        if(-1 == dfn[son]){
            Tarjan(G, son);
            low[v] = min(low[son], low[v]);
        }
        else if(1 == 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] = 0;
        }while(tmp != v);
        printf("\n");
    }
}

void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ){
    int i;
    
    for(i = 0; i < MaxVertices; i++){
        dfn[i] = -1;
        low[i] = in_stack[i] = 0;
    }
    top = -1;
    t = 0;
    
    for(i = 0; i < G->NumOfVertices; i++){
        if(-1 == dfn[i]){
            Tarjan(G, i);
        }
    }
}

 

PTA Strongly Connected Components