• 6-10 Strongly Connected Components (30分)


    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.

    找图的强连通分量,题目中的建图的函数没给出定义,实际使用邻接表。

    由于边数很少可以考虑先求所有边可达矩阵,mp[i][j]为1,表示存在i到j的路径,可以用邻接矩阵的n次方求得。然后排着判断即可,一个强连通分量里的点必定都是相互可达的。

    代码:

    #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 */
        int a,b;
        Graph G = (Graph)malloc(sizeof(GNode));
        scanf("%d%d",&G -> NumOfVertices,&G -> NumOfEdges);
        G -> Array = (PtrToVNode *)malloc(sizeof(PtrToVNode) * G -> NumOfVertices);
        for(int i = 0;i < G -> NumOfVertices;i ++) {
            G -> Array[i] = NULL;
        }
        for(int i = 0;i < G -> NumOfEdges;i ++) {
            scanf("%d%d",&a,&b);
            PtrToVNode p = (PtrToVNode)malloc(sizeof(VNode));
            p -> Vert = b;
            p -> Next = G -> Array[a];
            G -> Array[a] = p;
        }
        return G;
    }
    
    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 */
    void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ) {
        int mp[MaxVertices][MaxVertices] = {0},num = G -> NumOfVertices;
        int vis[MaxVertices] = {0};
        for(int i = 0;i < num;i ++) {
            PtrToVNode p = G -> Array[i];
            while(p) {
                mp[i][p -> Vert] = 1;
                p = p -> Next;
            }
        }
        for(int k = 0;k < num;k ++) {
            for(int i = 0;i < num;i ++) {
                for(int j = 0;j < num;j ++) {
                    if(mp[i][k] && mp[k][j]) mp[i][j] = 1;
                    //for(int l = 0;l < num;l ++) mp[i][j] |= mp[i][l] * mp[l][j]; //上一句可替换为这一句 可达矩阵的n - 1次方可以求出任意一点到另一点是否可达
                }
            }
        }
        for(int i = 0;i < num;i ++) {
            if(vis[i]) continue;
            visit(i);
            vis[i] = 1;
            for(int j = 0;j < num;j ++) {
                if(!vis[j] && mp[i][j] && mp[j][i]) {
                    vis[j] = 1;
                    visit(j);
                }
            }
            putchar('
    ');
        }
    }
  • 相关阅读:
    LintCode Update Bits
    LintCode Flip Bits
    LintCode Wood Cut
    LintCode Sqrt(x)
    LintCode Binary Search
    LintCode Subarray Sum Closest
    Huffman编码(Huffman树)
    DFS应用——查找强分支
    DFS应用——遍历有向图+判断有向图是否有圈
    DFS应用——找出无向图的割点
  • 原文地址:https://www.cnblogs.com/8023spz/p/12252266.html
Copyright © 2020-2023  润新知