Given an undirected graph with N vertices and E edges and two vertices (U, V) from the graph, the task is to detect if a path exists between these two vertices. Print “Yes” if a path exists and “No” otherwise.
Examples:
U = 1, V = 2
Output: No
Explanation:
There is no edge between the two points and hence its not possible to reach 2 from 1.Input:
U = 1, V = 3
Output: Yes
Explanation: Vertex 3 from vertex 1 via vertices 2 or 4.
Naive Approach:
The idea is to use Floyd Warshall Algorithm. To solve the problem, we need to try out all intermediate vertices ranging [1, N] and check:
- If there is a direct edge already which exists between the two nodes.
- Or we have a path from node i to intermediate node k and from node k to node j.
Below is the implementation of the above approach:
// C++ program to check if there is exist a path between // two vertices of an undirected graph. #include<bits/stdc++.h> using namespace std;
vector<vector< int >> adj;
// function to initialise // the adjacency matrix void init( int n)
{ for ( int i=1;i<=n;i++)
adj[i][i]=1;
} // Function to add edge between nodes void addEdge( int a, int b)
{ adj[a][b]=1;
adj[b][a]=1;
} // Function to compute the path void computePaths( int n)
{ // Use Floyd Warshall algorithm
// to detect if a path exists
for ( int k = 1; k <= n; k++)
{
// Try every vertex as an
// intermediate vertex
// to check if a path exists
for ( int i = 1; i <= n; i++)
for ( int j = 1; j <= n; j++)
adj[i][j] = adj[i][j] | (adj[i][k] && adj[k][j]);
}
} // Function to check if nodes are reachable bool isReachable( int s, int d)
{ if (adj[s][d] == 1)
return true ;
else
return false ;
} // Driver Code int main()
{ int n = 4;
adj = vector<vector< int >>(n+1,vector< int >(n+1,0));
init(n);
addEdge(1,2);
addEdge(2,3);
addEdge(1,4);
computePaths(n);
int u = 4, v = 3;
if (isReachable(u,v))
cout << "Yes\n" ;
else
cout << "No\n" ;
return 0;
} |
// Java program to detect if a path // exists between any two vertices // for the given undirected graph import java.util.Arrays;
public class GFG{
// Class representing a undirected // graph using matrix representation static class Graph
{ int V;
int [][] g;
public Graph( int V)
{
this .V = V;
// Rows may not be contiguous
g = new int [V + 1 ][V + 1 ];
for ( int i = 0 ; i < V + 1 ; i++)
{
// Initialize all entries
// as false to indicate
// that there are
// no edges initially
Arrays.fill(g[i], 0 );
}
// Initializing node to itself
// as it is always reachable
for ( int i = 1 ; i <= V; i++)
g[i][i] = 1 ;
}
// Function to add edge between nodes
void addEdge( int v, int w)
{
g[v][w] = 1 ;
g[w][v] = 1 ;
}
// Function to check if nodes are reachable
boolean isReachable( int s, int d)
{
if (g[s][d] == 1 )
return true ;
else
return false ;
}
// Function to compute the path
void computePaths()
{
// Use Floyd Warshall algorithm
// to detect if a path exists
for ( int k = 1 ; k <= V; k++)
{
// Try every vertex as an
// intermediate vertex
// to check if a path exists
for ( int i = 1 ; i <= V; i++)
{
for ( int j = 1 ; j <= V; j++)
g[i][j] = g[i][j] | ((g[i][k] != 0 &&
g[k][j] != 0 ) ? 1 : 0 );
}
}
}
}; // Driver code public static void main(String[] args)
{ Graph _g = new Graph( 4 );
_g.addEdge( 1 , 2 );
_g.addEdge( 2 , 3 );
_g.addEdge( 1 , 4 );
_g.computePaths();
int u = 4 , v = 3 ;
if (_g.isReachable(u, v))
System.out.println( "Yes" );
else
System.out.println( "No" );
} } // This code is contributed by sanjeev2552 |
# Python3 program to detect if a path # exists between any two vertices # for the given undirected graph # Class representing a undirected # graph using matrix # representation class Graph:
def __init__( self , V):
self .V = V
# Initialize all entries
# as false to indicate
# that there are
# no edges initially
self .g = [[ 0 for j in range ( self .V + 1 )]
for i in range ( self .V + 1 )]
# Initializing node to itself
# as it is always reachable
for i in range ( self .V + 1 ):
self .g[i][i] = 1
# Function to add edge between nodes
def addEdge( self , v, w):
self .g[v][w] = 1
self .g[w][v] = 1
# Function to compute the path
def computePaths( self ):
# Use Floyd Warshall algorithm
# to detect if a path exists
for k in range ( 1 , self .V + 1 ):
# Try every vertex as an
# intermediate vertex
# to check if a path exists
for i in range ( 1 , self .V + 1 ):
for j in range ( 1 , self .V + 1 ):
self .g[i][j] = ( self .g[i][j] |
( self .g[i][k] and
self .g[k][j]))
# Function to check if nodes
# are reachable
def isReachable( self , s, d):
if ( self .g[s][d] = = 1 ):
return True
else :
return False
# Driver code if __name__ = = '__main__' :
_g = Graph( 4 )
_g.addEdge( 1 , 2 )
_g.addEdge( 2 , 3 )
_g.addEdge( 1 , 4 )
_g.computePaths()
u = 4
v = 3
if (_g.isReachable(u, v)):
print ( 'Yes' )
else :
print ( 'No' )
# This code is contributed by rutvik_56 |
// C# program to detect if a path // exists between any two vertices // for the given undirected graph using System;
public class GFG {
// Class representing a undirected
// graph using matrix representation
public
class Graph {
public
int V;
public
int [, ] g;
public Graph( int V)
{
this .V = V;
// Rows may not be contiguous
g = new int [V + 1, V + 1];
for ( int i = 0; i < V + 1; i++) {
// Initialize all entries
// as false to indicate
// that there are
// no edges initially
for ( int j = 0; j < V + 1; j++)
g[i, j] = 0;
}
// Initializing node to itself
// as it is always reachable
for ( int i = 1; i <= V; i++)
g[i, i] = 1;
}
// Function to add edge between nodes
public void addEdge( int v, int w)
{
g[v, w] = 1;
g[w, v] = 1;
}
// Function to check if nodes are reachable
public bool isReachable( int s, int d)
{
if (g[s, d] == 1)
return true ;
else
return false ;
}
// Function to compute the path
public void computePaths()
{
// Use Floyd Warshall algorithm
// to detect if a path exists
for ( int k = 1; k <= V; k++) {
// Try every vertex as an
// intermediate vertex
// to check if a path exists
for ( int i = 1; i <= V; i++) {
for ( int j = 1; j <= V; j++)
g[i, j] = g[i, j]
| ((g[i, k] != 0
&& g[k, j] != 0)
? 1
: 0);
}
}
}
};
// Driver code
public static void Main(String[] args)
{
Graph _g = new Graph(4);
_g.addEdge(1, 2);
_g.addEdge(2, 3);
_g.addEdge(1, 4);
_g.computePaths();
int u = 4, v = 3;
if (_g.isReachable(u, v))
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
} // This code is contributed by umadevi9616 |
<script> // Javascript program to detect if a path // exists between any two vertices // for the given undirected graph // Class representing a undirected // graph using matrix representation class Graph { constructor(V)
{
this .V = V;
// Rows may not be contiguous
this .g = new Array(V + 1);
for (let i = 0; i < V + 1; i++)
{
this .g[i] = new Array(V+1);
// Initialize all entries
// as false to indicate
// that there are
// no edges initially
for (let j = 0; j < (V + 1); j++)
{
this .g[i][j] = 0;
}
}
// Initializing node to itself
// as it is always reachable
for (let i = 1; i <= V; i++)
this .g[i][i] = 1;
}
// Function to add edge between nodes
addEdge(v, w)
{
this .g[v][w] = 1;
this .g[w][v] = 1;
}
// Function to check if nodes are reachable
isReachable(s, d)
{
if ( this .g[s][d] == 1)
return true ;
else
return false ;
}
// Function to compute the path
computePaths()
{
// Use Floyd Warshall algorithm
// to detect if a path exists
for (let k = 1; k <= this .V; k++)
{
// Try every vertex as an
// intermediate vertex
// to check if a path exists
for (let i = 1; i <= this .V; i++)
{
for (let j = 1; j <= this .V; j++)
this .g[i][j] = this .g[i][j] | (( this .g[i][k] != 0 &&
this .g[k][j] != 0) ? 1 : 0);
}
}
}
} // Driver code let _g = new Graph(4);
_g.addEdge(1, 2);
_g.addEdge(2, 3);
_g.addEdge(1, 4);
_g.computePaths();
let u = 4, v = 3;
if (_g.isReachable(u, v))
document.write( "Yes<br>" );
else
document.write( "No<br>" );
// This code is contributed by unknown2108 </script> |
Yes
Time Complexity: O(V3)
Auxiliary Space: O(V2)
Efficient Solutions
1) We can either use BFS or DFS to find if there is a path from u to v. Below is a BFS-based solution
// C++ program to check if there is exist a path between // two vertices of an undirected graph. #include<bits/stdc++.h> using namespace std;
vector<vector< int >> adj;
// function to add an edge to graph void addEdge( int v, int w)
{ adj[v].push_back(w);
adj[w].push_back(v);
} // A BFS based function to check whether d is reachable from s. bool isReachable( int s, int d)
{ // Base case
if (s == d)
return true ;
int n= ( int )adj.size();
// Mark all the vertices as not visited
vector< bool > visited(n, false );
// Create a queue for BFS
queue< int > q;
// Mark the current node as visited and enqueue it
visited[s]= true ;
q.push(s);
while (!q.empty())
{
// Dequeue a vertex from queue and print it
s=q.front();
q.pop();
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it
// visited and enqueue it
for ( auto x:adj[s])
{
// If this adjacent node is the destination node,
// then return true
if (x == d)
return true ;
// Else, continue to do BFS
if (!visited[x])
{
visited[x] = true ;
q.push(x);
}
}
}
// If BFS is complete without visiting d
return false ;
} // Driver program to test methods of graph class int main()
{ int n = 4;
// Create a graph in the above diagram
adj = vector<vector< int >>(n);
addEdge(0,1);
addEdge(0,2);
addEdge(1,2);
addEdge(2,0);
addEdge(2,3);
addEdge(3,3);
int u = 1, v = 3;
if (isReachable(u, v))
cout << "\n There is a path from " << u << " to " << v;
else
cout << "\n There is no path from " << u << " to " << v;
return 0;
} |
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
// Java program to check if there is exist a path between // two vertices of an undirected graph. public class Graph {
// This class represents an undirected graph
// using adjacency list representation
int V; // No. of vertices
// Pointer to an array containing adjacency lists
ArrayList<ArrayList<Integer>> adj;
Graph( int V){
this .V = V;
adj = new ArrayList<>();
for ( int i= 0 ;i<V;i++)
adj.add( new ArrayList<>());
}
// function to add an edge to graph
void addEdge( int v, int w)
{
adj.get(v).add(w);
adj.get(w).add(v);
}
// A BFS based function to check whether d is reachable from s.
boolean isReachable( int s, int d)
{
// Base case
if (s == d)
return true ;
// Mark all the vertices as not visited
boolean [] visited = new boolean [V];
for ( int i = 0 ; i < V; i++)
visited[i] = false ;
// Create a queue for BFS
Queue<Integer> queue = new LinkedList<>();
// Mark the current node as visited and enqueue it
visited[s] = true ;
queue.add(s);
while (!queue.isEmpty()) {
// Dequeue a vertex from queue and print it
s = queue.remove();
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it
// visited and enqueue it
for ( int i= 0 ; i<adj.get(s).size();i++) {
// If this adjacent node is the destination node,
// then return true
if (adj.get(s).get(i) == d)
return true ;
// Else, continue to do BFS
if (!visited[adj.get(s).get(i)]) {
visited[adj.get(s).get(i)] = true ;
queue.add(adj.get(s).get(i));
}
}
}
// If BFS is complete without visiting d
return false ;
}
// Driver program to test methods of graph class
public static void main(String[] args)
{
// Create a graph given in the above diagram
Graph g = new Graph( 4 );
g.addEdge( 0 , 1 );
g.addEdge( 0 , 2 );
g.addEdge( 1 , 2 );
g.addEdge( 2 , 0 );
g.addEdge( 2 , 3 );
g.addEdge( 3 , 3 );
int u = 1 , v = 3 ;
if (g.isReachable(u, v))
System.out.println( "\n There is a path from " +u+ " to " +v);
else
System.out.println( "\n There is no path from " +u+ " to " +v);
}
} // This code is contributed by hritikrommie. |
# Python3 program to check if there is exist a path between # two vertices of an undirected graph. from collections import deque
def addEdge(v, w):
global adj
adj[v].append(w)
adj[w].append(v)
# A BFS based function to check whether d is reachable from s. def isReachable(s, d):
# Base case
if (s = = d):
return True
# Mark all the vertices as not visited
visited = [ False for i in range (V)]
# Create a queue for BFS
queue = deque()
# Mark the current node as visited and enqueue it
visited[s] = True
queue.append(s)
while ( len (queue) > 0 ):
# Dequeue a vertex from queue and print
s = queue.popleft()
# queue.pop_front()
# Get all adjacent vertices of the dequeued vertex s
# If a adjacent has not been visited, then mark it
# visited and enqueue it
for i in adj[s]:
# If this adjacent node is the destination node,
# then return true
if (i = = d):
return True
# Else, continue to do BFS
if ( not visited[i]):
visited[i] = True
queue.append(i)
# If BFS is complete without visiting d
return False
# Driver program to test methods of graph class if __name__ = = '__main__' :
# Create a graph given in the above diagram
V = 4
adj = [[] for i in range (V + 1 )]
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 2 )
addEdge( 2 , 0 )
addEdge( 2 , 3 )
addEdge( 3 , 3 )
u,v = 1 , 3
if (isReachable(u, v)):
print ( "There is a path from" ,u, "to" ,v)
else :
print ( "There is no path from" ,u, "to" ,v)
# This code is contributed by mohit kumar 29.
|
using System;
using System.Collections.Generic;
// C# program to check if there is exist a path between // two vertices of an undirected graph. public class Graph
{ // This class represents an undirected graph
// using adjacency list representation
int V; // No. of vertices
// Pointer to an array containing adjacency lists
List<List< int >> adj;
Graph( int V){
this .V = V;
adj = new List<List< int >>();
for ( int i = 0; i < V; i++)
adj.Add( new List< int >());
}
// function to add an edge to graph
void addEdge( int v, int w)
{
adj[v].Add(w);
adj[w].Add(v);
}
// A BFS based function to check whether d is reachable from s.
bool isReachable( int s, int d)
{
// Base case
if (s == d)
return true ;
// Mark all the vertices as not visited
bool [] visited = new bool [V];
for ( int i = 0; i < V; i++)
visited[i] = false ;
// Create a queue for BFS
Queue< int > queue = new Queue< int >();
// Mark the current node as visited and enqueue it
visited[s] = true ;
queue.Enqueue(s);
while (queue.Count != 0)
{
// Dequeue a vertex from queue and print it
s = queue.Dequeue();
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it
// visited and enqueue it
for ( int i = 0; i < adj[s].Count; i++) {
// If this adjacent node is the destination node,
// then return true
if (adj[s][i] == d)
return true ;
// Else, continue to do BFS
if (!visited[adj[s][i]]) {
visited[adj[s][i]] = true ;
queue.Enqueue(adj[s][i]);
}
}
}
// If BFS is complete without visiting d
return false ;
}
// Driver program to test methods of graph class
public static void Main(String[] args)
{
// Create a graph given in the above diagram
Graph g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
int u = 1, v = 3;
if (g.isReachable(u, v))
Console.WriteLine( "\n There is a path from " +u+ " to " +v);
else
Console.WriteLine( "\n There is no path from " +u+ " to " +v);
}
} // This code is contributed by umadevi9616 |
<script> // javascript program to check if there is exist a path between // two vertices of an undirected graph. // This class represents an undirected graph
// using adjacency list representation
var V; // No. of vertices
// Pointer to an array containing adjacency lists
var adj;
V = 4;
adj = new Array();
for ( var i = 0; i < V; i++)
adj.push( new Array());
// function to add an edge to graph
function addEdge(v , w) {
adj[v].push(w);
adj[w].push(v);
}
// A BFS based function to check whether d is reachable from s.
function isReachable(s , d) {
// Base case
if (s == d)
return true ;
// Mark all the vertices as not visited
var visited = new Array(V).fill( false );
// Create a queue for BFS
var queue = new Array();
// Mark the current node as visited and enqueue it
visited[s] = true ;
queue.push(s);
while (queue.length != 0)
{
// Dequeue a vertex from queue and print it
s = queue.pop();
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it
// visited and enqueue it
for ( var i = 0; i < adj[s].length; i++) {
// If this adjacent node is the destination node,
// then return true
if (adj[s][i] == d)
return true ;
// Else, continue to do BFS
if (!visited[adj[s][i]]) {
visited[adj[s][i]] = true ;
queue.push(adj[s][i]);
}
}
}
// If BFS is complete without visiting d
return false ;
}
// Driver program to test methods of graph class
// Create a graph given in the above diagram
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 2);
addEdge(2, 0);
addEdge(2, 3);
addEdge(3, 3);
var u = 1, v = 3;
if (isReachable(u, v))
document.write( "\n There is a path from " + u + " to " + v);
else
document.write( "\n There is no path from " + u + " to " + v);
// This code is contributed by gauravrajput1 </script> |
There is a path from 1 to 3
Time Complexity: O(V + E)
Auxiliary Space: O(V)
The Recursive Approach
It Basically create a adjacency list then traverse over the source list and the that come under source list
while traversing if we get the destination then we will return true if not then false at the end.
#include<bits/stdc++.h> #include<iostream> using namespace std;
vector<vector< int >> graph;
void addEdge( int v, int w)
{ graph[v].push_back(w);
graph[w].push_back(v);
} bool checkpath(vector< int >adj[],vector< int >&vis, int n, int source, int destination){
if (source==destination) return 1;
vis=1;
for ( auto it:adj){
if (!vis[it]){
bool s=checkpath(adj,vis,n,it,destination);
if (s==1) return 1;
}
}
return 0;
}
bool Path( int n, vector<vector< int >>& edges, int source, int destination) {
vector< int >adj[n];
if (source==destination) return 1;
for ( int i=0;i<edges.size();i++){
adj[edges[i][0]].push_back(edges[i][1]);
adj[edges[i][1]].push_back(edges[i][0]);
}vector< int >vis(n,0);
return checkpath(adj,vis,n,source,destination);
}
int main(){
int n = 4;
// Create a graph in the above diagram
graph = vector<vector< int >>(n);
addEdge(0,1);
addEdge(0,2);
addEdge(1,2);
addEdge(2,0);
addEdge(2,3);
addEdge(3,3);
int u = 1, v = 3;
if (Path(n, graph, u, v))
cout << "\n There is a path from " << u << " to " << v;
else
cout << "\n There is no path from " << u << " to " << v;
return 0;
} |
// Java code for the above approach import java.io.*;
import java.util.*;
class Graph {
int V;
LinkedList<Integer>[] adj;
Graph( int V)
{
this .V = V;
adj = new LinkedList[V];
for ( int i = 0 ; i < V; i++) {
adj[i] = new LinkedList<>();
}
}
void addEdge( int v, int w)
{
adj[v].add(w);
adj[w].add(v);
}
// Function to check if there is a path between source
// and destination
boolean checkPath( int source, int destination,
boolean [] visited)
{
// if source and destination are same, return True
if (source == destination) {
return true ;
}
visited = true ;
// Iterate through the neighbours of the current
// node
for (Integer i : adj) {
// If the neighbour is not visited yet
if (!visited[i]) {
if (checkPath(i, destination, visited)) {
return true ;
}
}
}
return false ;
}
boolean Path( int source, int destination)
{
boolean [] visited = new boolean [V];
return checkPath(source, destination, visited);
}
} class GFG {
public static void main(String[] args)
{
Graph g = new Graph( 4 );
// Create a graph in the above diagram
g.addEdge( 0 , 1 );
g.addEdge( 0 , 2 );
g.addEdge( 1 , 2 );
g.addEdge( 2 , 0 );
g.addEdge( 2 , 3 );
g.addEdge( 3 , 3 );
// Given source and destination
int source = 1 , destination = 3 ;
// Function call
if (g.Path(source, destination)) {
System.out.println( "There is a path from "
+ source + " to "
+ destination);
}
else {
System.out.println( "There is no path from "
+ source + " to "
+ destination);
}
}
} // This code is contributed by karthik. |
from collections import defaultdict
# Create an empty graph graph = defaultdict( list )
# Function to add edges to the graph def addEdge(v, w):
graph[v].append(w)
graph[w].append(v)
# Function to check if there is a path between source and destination def checkpath(adj, vis, n, source, destination):
# if source and destination are same, return True
if source = = destination:
return True
vis = 1
# Iterate through the neighbours of the current node
for it in adj:
# If the neighbour is not visited yet
if not vis[it]:
s = checkpath(adj, vis, n, it, destination)
if s:
return True
return False
def Path(n, edges, source, destination):
adj = defaultdict( list )
# Create the adjacency list from the edges
for i in range ( len (edges)):
adj[edges[i][ 0 ]].append(edges[i][ 1 ])
adj[edges[i][ 1 ]].append(edges[i][ 0 ])
# Initialize the visited array
vis = [ 0 ] * n
# check if there is a path between source and
return checkpath(adj, vis, n, source, destination)
if __name__ = = "__main__" :
n = 4
# Add edges to the graph
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 2 )
addEdge( 2 , 0 )
addEdge( 2 , 3 )
addEdge( 3 , 3 )
# Given source and destination
u = 1
v = 3
# Function call
if Path(n, graph, u, v):
print ( "There is a path from" , u, "to" , v)
else :
print ( "There is no path from" , u, "to" , v)
# This code is contributed by lokeshpotta20
|
using System;
using System.Collections.Generic;
class Graph
{ int V;
LinkedList< int >[] adj;
public Graph( int V)
{
this .V = V;
adj = new LinkedList< int >[V];
for ( int i = 0; i < V; i++)
{
adj[i] = new LinkedList< int >();
}
}
public void addEdge( int v, int w)
{
adj[v].AddLast(w);
adj[w].AddLast(v);
}
// Function to check if there is a path between source
// and destination
bool checkPath( int source, int destination, bool [] visited)
{
// if source and destination are same, return True
if (source == destination)
{
return true ;
}
visited = true ;
// Iterate through the neighbours of the current node
foreach ( int i in adj)
{
// If the neighbour is not visited yet
if (!visited[i])
{
if (checkPath(i, destination, visited))
{
return true ;
}
}
}
return false ;
}
public bool Path( int source, int destination)
{
bool [] visited = new bool [V];
return checkPath(source, destination, visited);
}
} class GFG
{ static void Main( string [] args)
{
Graph g = new Graph(4);
// Create a graph in the above diagram
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
// Given source and destination
int source = 1, destination = 3;
// Function call
if (g.Path(source, destination))
{
Console.WriteLine( "There is a path from "
+ source + " to "
+ destination);
}
else
{
Console.WriteLine( "There is no path from "
+ source + " to "
+ destination);
}
}
} |
//Javascript code for the above approach const graph = new Map();
function addEdge(v, w) {
if (graph.has(v)) {
graph.get(v).push(w);
} else {
graph.set(v, [w]);
}
if (graph.has(w)) {
graph.get(w).push(v);
} else {
graph.set(w, [v]);
}
} function checkpath(adj, vis, n, source, destination) {
if (source === destination) return 1;
vis = 1;
for (let i = 0; i < adj.length; i++) {
if (!vis[adj[i]]) {
let s = checkpath(adj, vis, n, adj[i], destination);
if (s === 1) return 1;
}
}
return 0;
} function Path(n, edges, source, destination) {
if (source === destination) return 1;
const adj = new Array(n).fill(0).map(() => []);
for (let i = 0; i < edges.length; i++) {
adj[edges[i][0]].push(edges[i][1]);
adj[edges[i][1]].push(edges[i][0]);
}
const vis = new Array(n).fill(0);
return checkpath(adj, vis, n, source, destination);
} //Driver code const n = 4; addEdge(0, 1); addEdge(0, 2); addEdge(1, 2); addEdge(2, 0); addEdge(2, 3); addEdge(3, 3); const u = 1, v = 3; if (Path(n, graph, u, v)) {
document.write( "There is a path from " + u + " to " + v);
} else {
document.write( "There is no path from " + u + " to " + v);
} |
There is a path from 1 to 3
Below is the DFS-based solution
// C++ program to check if there is exist a path between // two vertices of an undirected graph. #include<bits/stdc++.h> using namespace std;
vector<vector< int >> graph;
void addEdge( int v, int w)
{ graph[v].push_back(w);
graph[w].push_back(v);
} bool dfs(vector< int > adj[], vector< int > &vis, int start, int end);
bool validPath( int n, vector<vector< int >>& edges, int start, int end);
bool validPath( int n, vector<vector< int >>& edges, int start, int end) {
vector< int > adj[n];
for ( int i=0; i<edges.size(); i++){
int u = edges[i][0];
int v = edges[i][1];
adj[u].push_back(v);
adj[v].push_back(u);
}
vector < int > vis(n, 0);
for ( int i=0; i<n; i++)
if (vis[i] == 0)
if (dfs(adj, vis, start, end))
return true ;
return false ;
}
bool dfs(vector< int > adj[], vector< int > &vis, int start, int end){
if (end == start)
return true ;
vis[start] = 1;
for ( auto it: adj[start])
if (vis[it]==0)
if (dfs(adj, vis, it, end))
return true ;
return false ;
}
int main()
{ int n = 4;
// Create a graph in the above diagram
graph = vector<vector< int >>(n);
addEdge(0,1);
addEdge(0,2);
addEdge(1,2);
addEdge(2,0);
addEdge(2,3);
addEdge(3,3);
int u = 1, v = 3;
if (validPath(n, graph, u, v))
cout << "\n There is a path from " << u << " to " << v;
else
cout << "\n There is no path from " << u << " to " << v;
return 0;
} |
import java.util.ArrayList;
public class CheckPathInUndirectedGraph
{ // Define a graph using an ArrayList of ArrayLists of Integers
static ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
// Function to add an undirected edge between two vertices
static void addEdge( int v, int w) {
graph.get(v).add(w);
graph.get(w).add(v);
}
// Function to perform DFS traversal on the graph
static boolean dfs(ArrayList<Integer>[] adj,
ArrayList<Integer> vis,
int start, int end) {
// If the end vertex is reached, return true
if (end == start) {
return true ;
}
// Mark the current vertex as visited
vis.set(start, 1 );
// Traverse the adjacent vertices of the current vertex
for ( int it : adj[start]) {
// If the adjacent vertex has not been visited,
// recursively call the dfs function
if (vis.get(it) == 0 ) {
if (dfs(adj, vis, it, end)) {
return true ;
}
}
}
// If there is no path between the vertices, return false
return false ;
}
// Function to check if a path exists between two vertices
static boolean validPath( int n, int [][] edges, int start, int end)
{
// Create the adjacency list representation of the graph
ArrayList<Integer>[] adj = new ArrayList[n];
for ( int i = 0 ; i < n; i++) {
adj[i] = new ArrayList<Integer>();
}
for ( int i = 0 ; i < edges.length; i++) {
int u = edges[i][ 0 ];
int v = edges[i][ 1 ];
adj[u].add(v);
adj[v].add(u);
}
// Create an array to mark visited vertices
ArrayList<Integer> vis = new ArrayList<>(n);
for ( int i = 0 ; i < n; i++) {
vis.add( 0 );
}
// Traverse the graph using DFS and return true if a path is found between the vertices
for ( int i = 0 ; i < n; i++) {
if (vis.get(i) == 0 ) {
if (dfs(adj, vis, start, end)) {
return true ;
}
}
}
// If there is no path between the vertices, return false
return false ;
}
// Main function to test the code
public static void main(String[] args) {
int n = 4 ;
// Initialize the graph with empty ArrayLists
for ( int i = 0 ; i < n; i++) {
graph.add( new ArrayList<>());
}
// Add the edges to the graph
addEdge( 0 , 1 );
addEdge( 0 , 2 );
addEdge( 1 , 2 );
addEdge( 2 , 0 );
addEdge( 2 , 3 );
addEdge( 3 , 3 );
int u = 1 , v = 3 ;
// Check if there is a path between u and v
if (validPath(n, new int [][]{{ 0 , 1 },{ 0 , 2 },{ 1 , 2 },{ 2 , 0 },{ 2 , 3 },{ 3 , 3 }}, u, v)) {
System.out.println( "There is a path from " + u + " to " + v);
} else {
System.out.println( "There is no path from " + u + " to " + v);
}
}
} |
# Python program for the above approach: graph = []
def addEdge(v, w):
global graph
graph[v].append(w)
graph[w].append(v)
def dfs(adj, vis, start, end):
if (end = = start):
return True
vis[start] = 1 ;
for it in adj[start]:
if (vis[it] = = 0 ):
if (dfs(adj, vis, it, end)):
return True
return False
def validPath(n, edges, start, end):
adj = [[] for _ in range (n)]
for i in range ( len (edges)):
u = edges[i][ 0 ]
v = edges[i][ 1 ]
adj[u].append(v)
adj[v].append(u)
vis = [ 0 ] * n
for i in range (n):
if (vis[i] = = 0 ):
if (dfs(adj, vis, start, end)):
return True
return False
## Driver code n = 4
## Create a graph in the above diagram graph = [[] for _ in range (n)];
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 2 )
addEdge( 2 , 0 )
addEdge( 2 , 3 )
addEdge( 3 , 3 )
u = 1
v = 3
if (validPath(n, graph, u, v)):
print ( "There is a path from" , u, "to" , v)
else :
print ( "There is no path from" , u, "to" , v)
# This code is contributed by subhamgoyal2014.
|
// C# program to check if there is exist a path between // two vertices of an undirected graph. using System;
using System.Collections.Generic;
class Graph
{ List<List< int >> adj;
public Graph( int n) {
adj = new List<List< int >>(n);
for ( int i=0; i<n; i++)
adj.Add( new List< int >());
}
// Function to add an undirected edge between two vertices
public void AddEdge( int v, int w) {
adj[v].Add(w);
adj[w].Add(v);
}
// Function to perform DFS traversal on the graph
bool dfs(List< int >[] adj, int [] vis, int start, int end) {
// If the end vertex is reached, return true
if (end == start)
return true ;
vis[start] = 1;
foreach ( int i in adj[start])
if (vis[i] == 0)
if (dfs(adj, vis, i, end))
return true ;
return false ;
}
// Function to check if a path exists between two vertices
public bool ValidPath( int start, int end) {
int n = adj.Count;
int [] vis = new int [n];
for ( int i=0; i<n; i++)
vis[i] = 0;
for ( int i=0; i<n; i++)
if (vis[i] == 0)
if (dfs(adj.ToArray(), vis, start, end))
return true ;
return false ;
}
} public class Gfg
{ public static void Main() {
int n = 4;
Graph graph = new Graph(n);
graph.AddEdge(0, 1);
graph.AddEdge(0, 2);
graph.AddEdge(1, 2);
graph.AddEdge(2, 0);
graph.AddEdge(2, 3);
graph.AddEdge(3, 3);
int u = 1, v = 3;
if (graph.ValidPath(u, v))
Console.WriteLine( "\n There is a path from " + u + " to " + v);
else
Console.WriteLine( "\n There is no path from " + u + " to " + v);
}
} |
let graph = []; function addEdge(v, w) {
graph[v].push(w);
graph[w].push(v);
} function dfs(adj, vis, start, end) {
if (end === start) {
return true ;
}
vis[start] = 1;
for (let i = 0; i < adj[start].length; i++) {
let it = adj[start][i];
if (vis[it] === 0) {
if (dfs(adj, vis, it, end)) {
return true ;
}
}
}
return false ;
} function validPath(n, edges, start, end) {
let adj = new Array(n);
for (let i = 0; i < n; i++) {
adj[i] = [];
}
for (let i = 0; i < edges.length; i++) {
let u = edges[i][0];
let v = edges[i][1];
adj[u].push(v);
adj[v].push(u);
}
let vis = new Array(n).fill(0);
for (let i = 0; i < n; i++) {
if (vis[i] === 0) {
if (dfs(adj, vis, start, end)) {
return true ;
}
}
}
return false ;
} let n = 4; graph = new Array(n);
for (let i = 0; i < n; i++) {
graph[i] = [];
} addEdge(0, 1); addEdge(0, 2); addEdge(1, 2); addEdge(2, 0); addEdge(2, 3); addEdge(3, 3); let u = 1, v = 3; if (validPath(n, graph, u, v)) {
console.log(`There is a path from ${u} to ${v}`);
} else {
console.log(`There is no path from ${u} to ${v}`);
} |
There is a path from 1 to 3
2) We can use disjoint-set data structure (also called union find) to find there is a path from vertex u to vertex v.
#include <bits/stdc++.h> #include <iostream> using namespace std;
vector<vector< int > > graph;
void addEdge( int v, int w)
{ graph[v].push_back(w);
graph[w].push_back(v);
} class UnionFind {
vector< int > parent, rank;
public :
UnionFind( int n) : parent(n), rank(n, 1)
{
iota(parent.begin(), parent.end(), 0);
}
// Function to find the parent of vertex
int find( int x)
{
if (x != parent[x]) {
parent[x] = find(parent[x]);
}
return parent[x];
}
// Function to unite the vertices
void unite( int x, int y)
{
int parentX = find(x), parentY = find(y);
// If both vertices does not belong to same set, unite them
if (parentX != parentY) {
if (rank[parentX] > rank[parentY]) {
swap(parentX, parentY);
}
// Modify the parent of the smaller group as the
// parent of the larger group, also increment
// the size of the larger group.
parent[parentX] = parentY;
rank[parentY] += rank[parentX];
}
}
}; bool validPath( int n, vector<vector< int > >& adj, int source,
int destination)
{ UnionFind uf(n);
for ( int i = 0; i < n; i++) {
int u = i;
for ( auto v : adj[i]) {
uf.unite(u, v);
}
}
return uf.find(source) == uf.find(destination);
} int main()
{ int n = 4;
// Create a graph in the above diagram
graph = vector<vector< int > >(n);
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 2);
addEdge(2, 0);
addEdge(2, 3);
addEdge(3, 3);
int u = 1, v = 3;
if (validPath(n, graph, u, v))
cout << "There is a path from " << u << " to "
<< v << endl;
else
cout << "There is no path from " << u << " to "
<< v << endl;
return 0;
} |
import java.util.*;
class Graph {
List<List<Integer> > adjList;
public Graph( int n)
{
adjList = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
adjList.add( new ArrayList<>());
}
}
public void addEdge( int v, int w)
{
adjList.get(v).add(w);
adjList.get(w).add(v);
}
} class UnionFind {
int [] parent;
int [] rank;
public UnionFind( int n)
{
parent = new int [n];
rank = new int [n];
for ( int i = 0 ; i < n; i++) {
parent[i] = i;
rank[i] = 1 ;
}
}
// Function to find the parent of vertex
public int find( int x)
{
if (x != parent[x]) {
parent[x] = find(parent[x]);
}
return parent[x];
}
// Function to unite the vertices
public void unite( int x, int y)
{
int parentX = find(x), parentY = find(y);
// If both vertices does not belong to same set, unite them
if (parentX != parentY) {
if (rank[parentX] > rank[parentY]) {
int temp = parentX;
parentX = parentY;
parentY = temp;
}
// Modify the parent of the smaller group as the
// parent of the larger group, also increment
// the size of the larger group.
parent[parentX] = parentY;
rank[parentY] += rank[parentX];
}
}
} class Main {
public static boolean validPath( int n, Graph graph,
int source,
int destination)
{
UnionFind uf = new UnionFind(n);
for ( int i = 0 ; i < n; i++) {
int u = i;
for ( int v : graph.adjList.get(i)) {
uf.unite(u, v);
}
}
return uf.find(source) == uf.find(destination);
}
public static void main(String[] args)
{
int n = 4 ;
// Create a graph in the above diagram
Graph graph = new Graph(n);
graph.addEdge( 0 , 1 );
graph.addEdge( 0 , 2 );
graph.addEdge( 1 , 2 );
graph.addEdge( 2 , 0 );
graph.addEdge( 2 , 3 );
graph.addEdge( 3 , 3 );
int u = 1 , v = 3 ;
if (validPath(n, graph, u, v)) {
System.out.println( "There is a path from " + u
+ " to " + v);
}
else {
System.out.println( "There is no path from " + u
+ " to " + v);
}
}
} // This code is contributed By Prajwal Kandekar |
from typing import List
graph = []
def addEdge(v: int , w: int ) - > None :
graph[v].append(w)
graph[w].append(v)
class UnionFind:
def __init__( self , n: int ) - > None :
self .parent = list ( range (n))
self .rank = [ 1 ] * n
# Function to find the parent of vertex
def find( self , x: int ) - > int :
if x ! = self .parent[x]:
self .parent[x] = self .find( self .parent[x])
return self .parent[x]
# Function to unite the vertices
def unite( self , x: int , y: int ) - > None :
parentX, parentY = self .find(x), self .find(y)
# If both vertices does not belong to same set, unite them
if parentX ! = parentY:
if self .rank[parentX] > self .rank[parentY]:
parentX, parentY = parentY, parentX
# Modify the parent of the smaller group as the
# parent of the larger group, also increment
# the size of the larger group.
self .parent[parentX] = parentY
self .rank[parentY] + = self .rank[parentX]
def validPath(n: int , adj: List [ List [ int ]], source: int , destination: int ) - > bool :
uf = UnionFind(n)
for i in range (n):
u = i
for v in adj[i]:
uf.unite(u, v)
return uf.find(source) = = uf.find(destination)
if __name__ = = '__main__' :
n = 4
# Create a graph in the above diagram
graph = [[] for i in range (n)]
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 2 )
addEdge( 2 , 0 )
addEdge( 2 , 3 )
addEdge( 3 , 3 )
u, v = 1 , 3
if validPath(n, graph, u, v):
print (f "There is a path from {u} to {v}" )
else :
print (f "There is no path from {u} to {v}" )
|
// Define an empty array for the graph let graph = []; // Function to add edges to the graph function addEdge(v, w) {
graph[v].push(w);
graph[w].push(v);
} // Define the UnionFind class class UnionFind { constructor(n) {
this .parent = [...Array(n).keys()];
this .rank = Array(n).fill(1);
} // Function to find the parent of a vertex
find(x) {
if (x != this .parent[x]) {
this .parent[x] = this .find( this .parent[x]);
}
return this .parent[x];
}
// Function to unite two vertices
unite(x, y) {
let parentX = this .find(x);
let parentY = this .find(y);
// If both vertices do not belong to the same set, unite them
if (parentX != parentY) {
if ( this .rank[parentX] > this .rank[parentY]) {
[parentX, parentY] = [parentY, parentX];
}
// Modify the parent of the smaller group as the
// parent of the larger group, also increment
// the size of the larger group.
this .parent[parentX] = parentY;
this .rank[parentY] += this .rank[parentX];
}
}
} // Function to check if a valid path exists between two vertices function validPath(n, adj, source, destination) {
let uf = new UnionFind(n);
for (let i = 0; i < n; i++) {
let u = i;
for (let v of adj[i]) {
uf.unite(u, v);
}
}
return uf.find(source) == uf.find(destination);
} // Main function to test the algorithm if (require.main === module) {
const n = 4;
// Create a graph in the above diagram
graph = [...Array(n)].map(() => []);
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 2);
addEdge(2, 0);
addEdge(2, 3);
addEdge(3, 3);
const u = 1;
const v = 3;
if (validPath(n, graph, u, v)) {
console.log(`There is a path from ${u} to ${v}`);
} else {
console.log(`There is no path from ${u} to ${v}`);
}
} |
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{ static List<List< int >> graph;
static void Main()
{
int n = 4;
// Create a graph in the above diagram
graph = new List<List< int >>(n);
for ( int i = 0; i < n; i++)
{
graph.Add( new List< int >());
}
AddEdge(0, 1);
AddEdge(0, 2);
AddEdge(1, 2);
AddEdge(2, 0);
AddEdge(2, 3);
AddEdge(3, 3);
int u = 1, v = 3;
if (ValidPath(n, graph, u, v))
Console.WriteLine($ "There is a path from {u} to {v}" );
else
Console.WriteLine($ "There is no path from {u} to {v}" );
Console.ReadLine();
}
static void AddEdge( int v, int w)
{
graph[v].Add(w);
graph[w].Add(v);
}
class UnionFind
{
List< int > parent, rank;
public UnionFind( int n)
{
parent = Enumerable.Range(0, n).ToList();
rank = Enumerable.Repeat(1, n).ToList();
}
// Function to find the parent of vertex
public int Find( int x)
{
if (x != parent[x])
{
parent[x] = Find(parent[x]);
}
return parent[x];
}
// Function to unite the vertices
public void Unite( int x, int y)
{
int parentX = Find(x), parentY = Find(y);
// If both vertices does not belong to same set, unite them
if (parentX != parentY)
{
if (rank[parentX] > rank[parentY])
{
Swap( ref parentX, ref parentY);
}
// Modify the parent of the smaller group as the
// parent of the larger group, also increment
// the size of the larger group.
parent[parentX] = parentY;
rank[parentY] += rank[parentX];
}
}
private void Swap<T>( ref T x, ref T y)
{
T temp = x;
x = y;
y = temp;
}
}
static bool ValidPath( int n, List<List< int >> adj, int source,
int destination)
{
UnionFind uf = new UnionFind(n);
for ( int i = 0; i < n; i++)
{
int u = i;
foreach ( int v in adj[i])
{
uf.Unite(u, v);
}
}
return uf.Find(source) == uf.Find(destination);
}
} |
There is a path from 1 to 3
Time Complexity: O( E * ? ( V ) ) where ? is the Inverse Ackermann Function.
Auxiliary Space: O( V )