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('\n');
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM