程序来查找图的两个给定顶点之间是否存在路径

时间:2019-06-04 20:57:05

标签: c algorithm graph segmentation-fault breadth-first-search

我用C语言编写了以下代码,以查找图的两个给定顶点之间是否存在路径。最初,我要求用户提供输入,然后使用广度优先搜索来检查两个指定顶点之间是否存在路径。

此代码对于某些测试用例工作正常,但对其他一些测试则抛出分段错误。我要去哪里错了?

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

int main() {
    int v, e, e1, e2, t1, t2;

    printf("Enter num of vertices and edges: ");
    scanf("%d %d", &v, &e);
    int maze[v][v];

    for (int i = 0; i < v; i++)
        for (int j = 0; j < v; j++)
            maze[i][j] = 0;

    printf("Enter edges:\n")
    for (int i = 0; i < e; i++) {
        scanf("%d %d", &e1, &e2);
        maze[e1 - 1][e2 - 1] = 1;
        maze[e2 - 1][e1 - 1] = 1;
    }
    printf("The maze looks like:\n");
    for (int i = 0; i < v; i++) {
        for (int j = 0; j < v; j++) {
            printf("%d ", maze[i][j]);
        }
        printf("\n");
    }

    printf("enter target edges: ");
    scanf("%d %d", &t1, &t2);

    //BFS starts from here.
    int queue[v * v];
    int k = 1;

    queue[0] = t1 - 1;
    for (int i = 0; i < v; i++)
        if (maze[t1 - 1][i] == 1) {
            queue[k] = i;
             k++;
        }

    int bp, ep;

    bp = 0;
    ep = k;
    while (bp <= ep) {
        if (queue[bp] + 1 == t2) {
            printf("\npath exists\n");
            exit(0);
        } else {
            for(int i = 0; i < v; i++)
                if (maze[queue[bp + 1]][i] == 1) {
                    queue[k] = i;
                    k++;
                }       
        }
        bp = bp + 1;
        ep = k;
    }

    printf("\npath does'nt exist\n");
}

此代码适用的测试用例:

    Testcase-1:
    4 2
    1 2
    3 2
    1 3

    Testcase-2:
    4 2
    1 2
    3 2
    1 4

    TestCase-3:
    7 6
    0 1
    0 2
    1 3
    1 4
    1 6
    5 6
    1 6

我遇到细分错误的测试用例:

    TestCase-4:
    7 6
    0 1
    0 2
    1 3
    1 4
    1 6
    5 6
    0 6

    TestCase-5:
    7 6
    0 1
    0 2
    1 3
    1 4
    1 6
    5 6
    2 4

2 个答案:

答案 0 :(得分:1)

尽管测试用例中存在错误,但是您的代码还是有一些问题,其中包括:

  • 您将ep保留为队列中下一个可用元素的索引,但是循环条件会将其视为最后使用的元素:
    while (bp <= ep) {
  • 您不会遍历排队的第一个顶点的边缘。您将其移到第二个位置:
                if (maze[queue[bp + 1]][i] == 1) {
  • 您查找超过排队的最后一个顶点的两个顶点(已经引用了相同的行)

  • 您没有避免多次访问同一顶点的机制,所以

    1. 当原则上只需要线性时,您使用二次队列空间
    2. 但这还不够,因为如果起始顶点是循环的一部分但未连接到所需的终止顶点,那么BFS将永远不会终止(直到程序崩溃)。

答案 1 :(得分:0)

这种方法是正确的,但是在以后的测试用例中,我从'0'开始索引,这就是为什么我会遇到分段错误的原因,因此,如果顶点标签从1开始,则此代码可以正常工作。