【问题标题】:Graph connected and Connected component图连接和连接组件
【发布时间】:2016-07-28 00:39:29
【问题描述】:

我想知道一个图(连接矩阵)是否只与一个组件连接。当所有两个顶点 u 和 v 都包含从 u 到 v 的路径时,该图是连通的。 我的问题 3 种连接类型(抑制(-1),非连接(0),激活(1))我想如果 Aij != 0 有连接我使用 DFS 来搜索矩阵中有多少组件,但他适用于某些情况而不是对其他人。

例如我的矩阵(将 -1 替换为 1):

1, 0, 0, 1, 0,
1, 0, 1, 1, 1,
0, 0, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 1, 1, 1,

这里有一个representation of graph。当应用由Wisdom's Wind 创建的主题的相同答案 (DFS) 会导致 2 个组件来解决此添加第 39-47 行的问题时,有没有办法可以不用第 39-47 行?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define _MIN -1
#define _MAX 1
#define TAM 5
#define MAX TAM*TAM
#define QNT_MATRIX 1
#define SIZE_MATRIX MAX*QNT_MATRIX

void DFS(int *matrix, int *marks, int vertex, int componentes){
    int i;

    marks[vertex] = componentes;
    for(i=0; i<TAM; i++){
        if(matrix[vertex*TAM+i] != 0){
            if(marks[i] == 0){
                DFS(matrix, marks, i, componentes);
            }
        }
    }
}

int testDFS(int *matrix){
    int marks[TAM];
    int i, k, componentes=0, componentes_total=1;

    memset(marks, 0, TAM*sizeof(int));

    for(i=0; i<TAM; i++){
        if(marks[i] == 0){
            ++componentes;
            DFS(matrix, marks, i, componentes);
        }
    }

    for(i=0; i<TAM-1; i++){//line 39
        for(k=i+1; k<TAM; k++){
            if(marks[i] != marks[k]){
                if(matrix[i*TAM+k] == 0 && matrix[k*TAM+i] == 0){
                    componentes_total++;//no have way connection                
                }
            }
        }
    }//line47
    printf("testDFS Componentes: %d\n", componentes);
    printf("Componentes_total: %d\n", componentes_total);

}

int main(){
    int matrix[SIZE_MATRIX];
    int i;


    srand(time(NULL));

    for(i=0; i<SIZE_MATRIX; i++){
        scanf("%d,", &matrix[i]);
    }
    //Print matrix
    for(i=0; i<SIZE_MATRIX; i++){
        printf("%d ", matrix[i]);
        if((i+1)%TAM==0){
            printf("\n");
        }
        if((i+1)%(MAX)==0){
            printf("\n");
        }
    }

    testDFS(matrix);
    return 0;
}

【问题讨论】:

    标签: c++ graph depth-first-search


    【解决方案1】:

    只需对您的代码稍作调整,即可完成工作

    void DFS(int *matrix, int *marks, int vertex, int& componentes){
    int i;
    
    marks[vertex] = componentes;
    for(i=0; i<TAM; i++){
        if(matrix[vertex*TAM+i] != 0){
            if(marks[i] == 0){
                DFS(matrix, marks, i, componentes);
            }
            else if(marks[i] != marks[vertex]){
                marks[vertex] = marks[i];
                componentes = marks[i];
            }
        }
    }
    

    }

    实际上你的代码是对的。但是考虑一下这种情况,就像你上面的测试用例一样,节点 2 可以被 3、4、5 访问。但是 2 不能从任何地方访问。因此,根据您的逻辑,它的连接属性将为 2。但是,我添加的检查确保,如果“a”节点正在访问“b”节点并且“b”已经被访问,那么“a”与“b”连接并具有相同的连接值。

    【讨论】:

    • 谢谢你。你能解释一下为什么marks[vertex]会收到marks[i]而componentes会收到marks[i]吗?
    • 其实你的代码是对的。但是考虑一下情况,在你上面的测试用例中,节点2可以访问3,4,5。但是 2 不能从任何地方访问。因此,根据您的逻辑,它的连接属性将为 2。但是,我添加的检查确保,如果“a”节点正在访问“b”节点并且“b”已经被访问,那么“a”与“b”连接并且具有相同的连接值。
    • 我正在使用 matrix3x3={1, 0, 0, 0, 1, 1, 1, 1, 1} 进行测试,结果是 2 个组件(错误)。当 (testDFS i == 1) 有更多调用 DFS(i=2, C=2) 并以 C=2 结束(没有调用 DFS for i=2 因为标记[2] 为 2)时,这是错误的。我可以帮忙吗?
    • 我通过有条件地改变标记[i],标记[顶点]来改变!=一旦'a'访问'b'并且'b'已经被访问并且'a', 'b' 必须具有最低的组件值
    猜你喜欢
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 2012-10-13
    • 2016-10-08
    • 2012-05-05
    • 2015-01-25
    相关资源
    最近更新 更多