Connected Components in an undirected graph (C language)

≯℡__Kan透↙ 提交于 2020-12-15 05:20:28

问题


I'm trying to build a C program (that is, I don't have the facilities of the C ++ STL library) that prints the connected components in a non-direct graph. For example,
Input:
0 6
0 3
1 5
5 2
Output:
0 -> 6 -> 3
1 -> 5 -> 2
That is, there are two components. So far I've been able to build the code that counts the number of components and what builds the adjacency matrix, but I don't know how to connect the two.

First code:

#include <stdio.h>
#include <stdlib.h>
 
#define MAX 5000
int adj[MAX][MAX] = {0}; 


typedef struct {
    unsigned int first;
    unsigned int second;
} edge;

static void print_components(int *components, unsigned int order){
    unsigned int i;
    for (i = 0; i < order; i++) 
        printf("Vertice %u esta no grafo %d\n", i, components[i]);
    
}
 void connected_components_recursive(const edge *edges, unsigned int n, 
        int *components, unsigned int order, unsigned int vertex,
        unsigned int component){
    unsigned int i;
    components[vertex] = component; 
    for (i = 0; i < n; i++) {
        if (edges[i].first == vertex || edges[i].second == vertex) {
            const unsigned int neighbour = edges[i].first == vertex ?
                    edges[i].second : edges[i].first;
            if (components[neighbour] == -1) {
                connected_components_recursive(edges, n, components, order, neighbour, component);
            }
        }
    }
}
unsigned int connected_components(const edge *edges, unsigned int n, unsigned int order, 
        int **components){
    unsigned int i;
    unsigned int component = 0;
    *components = malloc(order * sizeof(int));
    if (components == NULL)
        return 0;
    for (i = 0; i < order; i++)
        (*components)[i] = -1;
    for (i = 0; i < order; i++) {
        if ((*components)[i] == -1) {
            connected_components_recursive(edges, n, *components, order, i, component);
            component++;
        }
    }
    return component;
}

int main(void){
    unsigned int order = 0; /* Vertices */
    unsigned int n = 0; /* Edges */
    edge *edges;
    int *components;
    unsigned int c;
    int x,y, qtd = 0;
    int max;
    scanf("%d", &maximo);
    for(int i = 0; i < max;i++)
        for(int j = 0; j < max;j++)
            adj[i][j]=0;
    while(scanf("%d %d", &x, &y)!=EOF){
        adj[x][y] = 1;
        adj[y][x] = 1;
    }
    
    for(int i = 0; i < max;i++){
        for(int k = 0; k < max; k++){
            if(adj[i][k]==1){
                order++;
                break;
            }
        }
        for(int j = 0; j < max;j++)
            if(adj[i][j]==1 && adj[j][i]==1){
                n++;
            }
    }
    n/=2;

    printf("There are %d edges and %d vertices\n",  n, order);
    
    
    
    
    return 0;
}

The max variable refers to the maximum possible value of a vertex. Just to avoid a very high complexity.

Second code:

#include <stdio.h>
#include <stdlib.h>
 
#define MAX 5000
int adj[MAX][MAX]; 
 
typedef struct {
    unsigned int first;
    unsigned int second;
} edge;

static void print_components(int *components, unsigned int order){
    unsigned int i;
    for (i = 0; i < order; i++) {
        printf("Vertex %u is in component %d\n", i, components[i]);
    }
}
 void connected_components_recursive(const edge *edges, unsigned int n, 
        int *components, unsigned int order, unsigned int vertex,
        unsigned int component)
{
    unsigned int i;
    /* Put this vertex in the current component */
    components[vertex] = component; 
    for (i = 0; i < n; i++) {
        if (edges[i].first == vertex || edges[i].second == vertex) {
            /* Adjacent */
            const unsigned int neighbour = edges[i].first == vertex ?
                    edges[i].second : edges[i].first;
            if (components[neighbour] == -1) {
                /* Not yet visited */
                connected_components_recursive(edges, n, components, order, neighbour, component);
            }
        }
    }
}
unsigned int connected_components(const edge *edges, unsigned int n, unsigned int order, 
        int **components){
    unsigned int i;
    unsigned int component = 0;
    *components = malloc(order * sizeof(int));
    if (components == NULL) {
        return 0;
    }
    for (i = 0; i < order; i++) {
        (*components)[i] = -1;
    }
     
    for (i = 0; i < order; i++) {
        if ((*components)[i] == -1) {
            connected_components_recursive(edges, n, *components, order, i, component);
            component++;
        }
    }
    return component;
}
int main(void){
    const unsigned int order = 6; /* Vertices */
    const unsigned int n = 4; /* Edges */
    edge *edges;
    int *components;
    unsigned int c;
    
    edges = malloc(n * sizeof(edge));
    if (edges == NULL) {
        return 1;
    }
    for(int i =0; i < n; i++){
        scanf("%d %d", &edges[i].first, &edges[i].second);
    }
    
 
    c = connected_components(edges, n, order, &components);
    if (components == NULL) {
        free(edges);
        return 1;
    }
    printf("There are %u components:\n", c);
    print_components(components, order);
    free(edges);
    free(components);
 
    return 0;
}

来源:https://stackoverflow.com/questions/65045904/connected-components-in-an-undirected-graph-c-language

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!