c++algorithmgraph-theorygraph-algorithmbreadth-first-search

Get path between 2 vertices using BFS in C++


I have written a code for this but it gives segmentation fault for disconnected graphs. It works fine for graphs that are connected. How can I overcome this error?

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;
}

I did a dry run of the code. It will first create adjacency matrix edges and mark all the edges in it. Visited array is used to keep track of all the vertices that have been visited till now so that there is no infinite loop. For the test case given below it will work till the queue contains 1 then it will pop 1 and the loop will end because there is no edge left that is connected to 1 and is not visited. After this the while loop should ideally break and as done==0 it should return an empty vector. I can't understand why the segmentation fault is coming.

The map is being used to keep track of which vertex was put in the queue by which vertex.

Doesn't work for the test case:

6 3
5 3
0 1
3 4
0 3

Below is the image of the graph for the above test case: enter image description here

Here we need to find the path from vertex 0 to 3. The input format is : Number of Vertices in the graph, Number of edges

Edges between the vertices (for E lines),

Vertices between which we need to find the path.


Solution

  • You are popping the BFS queue incorrectly. Instead of the inner for loop, which is executed |V| times for each entry in the queue, you should pop the queue in the outer loop, which is executed once for each element in the queue.

    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;
        }
    }
    

    Also, in main function of your code, there is a redundant expression !ans.empty() in the for loop where you are printing the answer(s).