Find if there is a path between two vertices in a directed graph


In computer science and graph theory, solutions to a variety of real-life model scenarios rely heavily on directed graphs. These specialized graphs consist of linked vertices anchored by directed edges pointing to other vertices. Determining if there's a pathway between two designated points is one typical quandary associated with using directed graphs. In this discourse, we explore diverse methods for resolving this dilemma using C++, including the required syntax for each procedure to keep things understandable. Further still, we'll present detailed algorithms meticulously illustrating each method and include two executable code examples.

Syntax

Its' essential to comprehend the language structure underpinning the methodology at play here before diving into particulars. Accordingly lets' first examine this syntax before proceeding to the code examples.

bool isPathExists(int startVertex, int endVertex, const vector<vector<int>>& graph);

Algorithm

Identifying a path between two vertices in a directed graph can be tackled using multiple techniques. This article will focus on discussing two widely used methods −

Approach 1: Depth-First Search (DFS)

  • Create a visited array to keep track of visited vertices during the traversal.

  • Initialize all elements of the visited array as false.

  • Mark the startVertex as visited.

  • If the startVertex is the same as the endVertex, return true as a path exists.

  • For each adjacent vertex of the current vertex, recursively call the isPathExists function with the adjacent vertex as the new startVertex.

  • If any recursive call returns true, return true.

  • If no recursive call returns true, return false.

Approach 2: Breadth-First Search (BFS)

  • Create a visited array to keep track of visited vertices during the traversal.

  • Initialize all elements of the visited array as false.

  • Create a queue to store the vertices to be processed.

  • Enqueue the startVertex into the queue and mark it as visited.

  • do the following things if queue is not empty −

  • Dequeue a vertex from the queue.

  • If the dequeued vertex is the same as the endVertex, return true as a path exists.

  • For each adjacent vertex of the dequeued vertex, if it is not visited, enqueue it into the queue and mark it as visited.

  • If the queue becomes empty and no path is found, return false.

Example 1: Depth-First Search (DFS) Approach

#include <iostream>
#include <vector>
using namespace std;

bool isPathExists(int startVertex, int endVertex, const vector<vector<int>>& graph) {
   vector<bool> visited(graph.size(), false);
   visited[startVertex] = true;
  
   if (startVertex == endVertex)
      return true;
  
   for (int adjVertex : graph[startVertex]) {
      if (!visited[adjVertex] && isPathExists(adjVertex, endVertex, graph))
         return true;
   }
  
   return false;
}

int main() {
   // Example usage
   int numVertices = 6;
   vector<vector<int>> graph(numVertices);
   graph[0] = {1, 2};
   graph[1] = {3};
   graph[2] = {1};
   graph[3] = {4, 5};
   graph[4] = {};
   graph[5] = {4};

   int startVertex = 0;
   int endVertex = 5;

   if (isPathExists(startVertex, endVertex, graph))
      cout << "A path exists between " << startVertex << " and " << endVertex << endl;
   else
      cout << "No path exists between " << startVertex << " and " << endVertex << endl;

   return 0;
}

Output

A path exists between 0 and 5

The code begins by defining a function called isPathExists that takes in the startVertex, endVertex, and the graph represented as an adjacency list. It initializes a boolean vector called visited to keep track of visited vertices. When executing this function, it first examines whether both the startVertex and endVertex are identical by comparing them.

When these vertices are identically positioned within this context, the function returns true immediately.

If this is not so and they differ from one another, another action is taken to check their adjacency to find if there exists a path between them or not.

This process involves iterating through adjacent vertices of the starting vertex repeatedly; with each iteration calling upon "isPathExists" recursively using newly searched vertices as fresh starting points to continue looking for an available route.This cycle repeats itself until either all possible pathways become exhausted or on stumbling upon one successful pathway.

If any of these recurrent calls detects any existing probable edge which connect both designated nodes(starting and ending),the output from such a screening will mean that indeed there is available interconnection between these two nodes.Hence,True will be returned at once.

Otherwise,a fail-safe loop action kicks in to detect when no available routes exist entirely as per complexity set in algorithm here.It returns False upon getting such an outcome,lamenting unsuccessful connectivity between the named nodes.

Example 2: Breadth-First Search (BFS) Approach

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

bool isPathExists(int startVertex, int endVertex, const vector<vector<int>>& graph) {
   vector<bool> visited(graph.size(), false);
   visited[startVertex] = true;
  
   queue<int> verticesQueue;
   verticesQueue.push(startVertex);
  
   while (!verticesQueue.empty()) {
      int currVertex = verticesQueue.front();
      verticesQueue.pop();
  
      if (currVertex == endVertex)
         return true;
  
      for (int adjVertex : graph[currVertex]) {
         if (!visited[adjVertex]) {
            visited[adjVertex] = true;
            verticesQueue.push(adjVertex);
         }
      }
   }
  
   return false;
}

int main() {
   // Example usage
   int numVertices = 6;
   vector<vector<int>> graph(numVertices);
   graph[0] = {1, 2};
   graph[1] = {3};
   graph[2] = {1};
   graph[3] = {4, 5};
   graph[4] = {};
   graph[5] = {4};

   int startVertex = 0;
   int endVertex = 5;

   if (isPathExists(startVertex, endVertex, graph))
      cout << "A path exists between " << startVertex << " and " << endVertex << endl;
   else
      cout << "No path exists between " << startVertex << " and " << endVertex << endl;

   return 0;
}

Output

A path exists between 0 and 5

The code defines the isPathExists function that takes in the startVertex, endVertex, and the graph represented as an adjacency list. It initializes a boolean vector called visited to keep track of visited vertices and a queue called verticesQueue to store the vertices to be processed.

The function starts by enqueuing the startVertex into the queue and marking it as visited. The functioning of our algorithm begins with entering into an iterative loop that persists for as long as there are still items present inside of its processing queue structure. As this structured repetition progresses each cycle performs two checks: Firstly verifying whether current iteration's dequeued vertex matches endpoint target specified earlier in execution; returning 'true' if both match successfully else proceeding on with next step which involves exploring nearby outlying points. During this exploration process, any adjacent unexplored vertices get the 'visited' tag before being placed in queue for deeper iterated checks and testing if they lead to an endVertex match.

In a case where there are no additions to queue after all exploration and verifications have triumphed, the function returns false.

Conclusion

Navigating the complexities of directed graphs can pose a fundamental concern within computer science development. To ease these challenges ranks among our objectives as we explore two prevalent methods implemented with C++. Depth-First Search (DFS) and Breadth-First Search (BFS) stand at the forefront of such techniques, providing procedural recipes that walk through each algorithm step-by-step while offering up working code samples for both models. Once mastered, such approaches spark new potential when it comes to addressing path-finding obstacles across multiple settings such as routing networks or analyzing social connections' frameworks while serving as valuable jumping-off points during enhancement development phases.

Updated on: 25-Jul-2023

407 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements