【问题标题】:Get path between 2 vertices using BFS in C++在 C++ 中使用 BFS 获取 2 个顶点之间的路径
【发布时间】:2018-12-27 05:17:14
【问题描述】:

我为此编写了一个代码,但它给出了断开连接图的分段错误。它适用于连接的图形。 我该如何克服这个错误?

vector<int> getPathBFS(int V, int** edges,int v1, int v2, int* visited, unordered_map<int,int> t)
{
    queue<int> q;
    q.push(v1);
    visited[v1]=1;
    int done=0;
    while(!q.empty() && done==0)
    {
        for(int i=0;i<V;i++)
        {
            int front=q.front();
            q.pop();
            if(edges[front][i]==1 && visited[i]!=1)
            {
                q.push(i);
                t[i]=front;
                visited[i]=1;
                if(i==v2)
                {
                    done=1;
                    break;
                }
            }
        }
    }
    vector<int> a;
    if(done==0)
        return a;
    else
    {
        int k=v2;
        a.push_back(v2);
        while(k!=v1)
        {
            k=t[k];
            a.push_back(k);
        }
        return a;
    }
}

int main()
{
    int V, E;
    cin >> V >> E;   
    int** edges=new int*[V];
    for(int i=0;i<V;i++)
    {
        edges[i]=new int[V];
        for(int j=0;j<V;j++)
        {
            edges[i][j]=0;
        }
    }

    for(int i=0;i<E;i++)
    {
        int f,s;
        cin>>f>>s;
        edges[f][s]=1;
        edges[s][f]=1;
    }
    int v1,v2;
    cin>>v1>>v2;

    int* visited=new int[V];
    for(int i=0;i<V;i++)
        visited[i]=0;
    unordered_map<int,int> t;
    t[v2]=0;
    vector<int> ans=getPathBFS(V,edges,v1,v2,visited,t);
    for(int i=0;i<ans.size();i++ && !ans.empty())
    {
        cout<<ans[i]<<" ";
    }

    delete [] visited;
    for(int i=0;i<V;i++)
    {
        delete [] edges[i];
    }

    delete [] edges;

    return 0;
}

我对代码进行了试运行。它将首先创建邻接矩阵边缘并标记其中的所有边缘。访问过的数组用于跟踪到目前为止已经访问过的所有顶点,从而不存在无限循环。 对于下面给出的测试用例,它将一直工作到队列包含 1 然后它将弹出 1 并且循环将结束,因为没有剩余的边连接到 1 并且未被访问。在此之后,while 循环应该理想地中断,并且作为 done==0 它应该返回一个空向量。我不明白为什么会出现分段错误。

地图用于跟踪哪个顶点被哪个顶点放入队列中。

不适用于测试用例:

6 3
5 3
0 1
3 4
0 3

以下是上述测试用例的图表图像:

这里我们需要找到从顶点 0 到 3 的路径。 输入格式为: 图中的顶点数,边数

顶点之间的边(对于 E 线),

我们需要找到路径的顶点。

【问题讨论】:

  • 在内部for 循环中,您不检查q 是否不为空,如果队列为空,则调用front 方法会导致段错误。
  • 您的问题标题提到了深度优先搜索(DFS),但您的代码示例向我们展示了您对广度优先搜索(BFS)的使用。哪个是正确的?
  • @ilim 是 BFS,很抱歉造成混乱
  • @AManoj 在未连接的图中,某些edges 项目未设置(0 值),因此您在 if 子句中的条件为假,然后您从 q 读取可能不存在的元素(首先q 中有一个元素,但在 for 循环中,您正在读取 V 元素)。
  • @rafix07 那是错误。非常感谢!

标签: c++ algorithm graph-theory graph-algorithm breadth-first-search


【解决方案1】:

您错误地弹出 BFS 队列。您应该在外部循环中弹出队列,而不是对队列中的每个条目执行|V| 次的内部 for 循环,该循环对队列中的每个元素执行一次。

vector<int> getPathBFS(int V, int** edges,int v1, int v2, int* visited, unordered_map<int,int> t)
{
    queue<int> q;
    q.push(v1);
    visited[v1]=1;
    int done=0;
    while(!q.empty() && done==0)
    {
        int front=q.front();
        q.pop();

        for(int i=0;i<V;i++)
        {
            if(edges[front][i]==1 && visited[i]!=1)
            {
                q.push(i);
                t[i]=front;
                visited[i]=1;
                if(i==v2)
                {
                    done=1;
                    break;
                }
            }
        }
    }
    vector<int> a;
    if(done==0)
        return a;
    else
    {
        int k=v2;
        a.push_back(v2);
        while(k!=v1)
        {
            k=t[k];
            a.push_back(k);
        }
        return a;
    }
}

此外,在您的代码的 main 函数中,您正在打印答案的 for 循环中有一个冗余表达式 !ans.empty()

【讨论】:

    猜你喜欢
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多