Given an undirected graph with N nodes and two vertices S & T, the task is to check if a cycle between these two vertices exists or not, such that no other node except S and T appear more than once in that cycle. Print Yes if it exists otherwise print No.
Example:
Input: N = 7, edges[][] = {{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 2}, {2, 6}, {6, 0}}, S = 0, T = 4
Output: No
Explanation:
Node 2 appears two times, in the only cycle that exists between 0 & 4
Input: N = 6, edges[][] = {{0, 1}, {0, 2}, {2, 5}, {3, 1}, {4, 5}, {4, 3}}, S = 0, T = 3
Output: Yes
Explanation:
Cycle between 0 and 3 is: 0->1->3->4->5->2->0
Approach:
If there exists a path back from T to S that doesn’t have any vertices of the path used to travel to T from S, then there will always be a cycle such that no other node except S and T appears more than once. Now, to solve the problem follow the steps below:
- Make an array visited of size n (where n is the number of nodes), and initialise it with all 0.
- Start a depth-first search from S, and put T as the destination.
- Change the value 0 of the current node to 1, in the visited array to keep the track of nodes visited in this path.
- If it is not possible to reach T, then there is no way a simple cycle could exist between them. So, print No.
- If T is reached, then change the destination to S and continue the depth-first search. Now, the nodes already visited can’t be visited again except S.
- If S is reached then print Yes, otherwise No.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to create graph void createGraph(vector<vector< int > >& graph,
vector<vector< int > >& edges)
{ for ( auto x : edges) {
// As it is an undirected graph
// so add an edge for both directions
graph[x[0]].push_back(x[1]);
graph[x[1]].push_back(x[0]);
}
} bool findSimpleCycle( int cur,
vector<vector< int > >& graph,
int start, int dest,
vector< bool >& visited,
bool flag)
{ // After reaching T, change the dest to S
if (!flag and cur == dest) {
dest = start;
flag = 1;
}
// If S is reached without touching a
// node twice except S and T,
// then return true
if (flag and cur == dest) {
return true ;
}
bool ans = 0;
visited[cur] = 1;
for ( auto child : graph[cur]) {
// A node can only be visited if it
// hasn't been visited or if it
// is S or t
if (!visited[child] or child == dest) {
ans = ans
| findSimpleCycle(
child, graph, start,
dest, visited, flag);
}
}
// Change visited of the current node
// to 0 while backtracking again so
// that all the paths can be traversed
visited[cur] = 0;
return ans;
} int main()
{ int nodes = 7;
vector<vector< int > > edges
= { { 0, 1 }, { 1, 2 }, { 2, 3 },
{ 3, 4 }, { 4, 5 }, { 5, 2 },
{ 2, 6 }, { 6, 0 } };
int S = 0, T = 4;
// To store the graph
vector<vector< int > > graph(nodes);
// To keep track of visited nodes
vector< bool > visited(nodes);
createGraph(graph, edges);
// If there exists a simple
// cycle between S & T
if (findSimpleCycle(S, graph,
S, T, visited, 0)) {
cout << "Yes" ;
}
// If no simple cycle exists
// between S & T
else {
cout << "No" ;
}
} |
import java.util.*;
class Graph {
// Function to create graph
static void createGraph(List<List<Integer>> graph,
List<List<Integer>> edges) {
for (List<Integer> x : edges) {
// As it is an undirected graph
// so add an edge for both directions
graph.get(x.get( 0 )).add(x.get( 1 ));
graph.get(x.get( 1 )).add(x.get( 0 ));
}
}
static boolean findSimpleCycle( int cur, List<List<Integer>> graph,
int start, int dest, boolean [] visited,
boolean flag) {
// After reaching T, change the dest to S
if (!flag && cur == dest) {
dest = start;
flag = true ;
}
// If S is reached without touching a
// node twice except S and T,
// then return true
if (flag && cur == dest) {
return true ;
}
boolean ans = false ;
visited[cur] = true ;
for ( int child : graph.get(cur)) {
// A node can only be visited if it
// hasn't been visited or if it
// is S or t
if (!visited[child] || child == dest) {
ans = ans
| findSimpleCycle(child, graph, start, dest, visited, flag);
}
}
// Change visited of the current node
// to 0 while backtracking again so
// that all the paths can be traversed
visited[cur] = false ;
return ans;
}
public static void main(String[] args) {
int nodes = 7 ;
List<List<Integer>> edges = Arrays.asList(
Arrays.asList( 0 , 1 ),
Arrays.asList( 1 , 2 ),
Arrays.asList( 2 , 3 ),
Arrays.asList( 3 , 4 ),
Arrays.asList( 4 , 5 ),
Arrays.asList( 5 , 2 ),
Arrays.asList( 2 , 6 ),
Arrays.asList( 6 , 0 )
);
int S = 0 , T = 4 ;
// To store the graph
List<List<Integer>> graph = new ArrayList<>();
for ( int i = 0 ; i < nodes; i++) {
graph.add( new ArrayList<Integer>());
}
// To keep track of visited nodes
boolean [] visited = new boolean [nodes];
createGraph(graph, edges);
// If there exists a simple
// cycle between S & T
if (findSimpleCycle(S, graph, S, T, visited, false )) {
System.out.println( "Yes" );
}
// If no simple cycle exists
// between S & T
else {
System.out.println( "No" );
}
}
} // this code is contributed by devendrasalunke |
# Function to create graph def createGraph(edges, N):
graph = list ([] for _ in range (N))
for node1, node2 in edges:
# As it is an undirected graph,
# add an edge for both directions
graph[node1].append(node2)
graph[node2].append(node1)
return graph
def findSimpleCycle(cur,
graph,
start, dest,
visited,
flag):
# After reaching T, change the dest to S
if (( not flag) and cur = = dest):
dest = start
flag = True
# If S is reached without touching a
# node twice except S and T,
# then return true
if ( not flag and cur = = dest):
return True
# first guess is that there is no cycle
# so ans is False.
# if we find one cycle, ans will be true
# and then returned .
ans = False
# mark node as visited in this path
visited[cur] = True
for child in graph[cur]:
# A node can only be visited if it
# hasn't been visited or if it
# is S or t
if ( not visited[child]) or child = = dest:
ans = ans or findSimpleCycle(
child, graph, start,
dest, visited, flag)
# Change visited of the current node
# to 0 while backtracking again so
# that all the paths can be traversed
visited[cur] = False
return ans
if __name__ = = "__main__" :
N = 7 # number of nodes
edges = [[ 0 , 1 ], [ 1 , 2 ], [ 2 , 3 ],
[ 3 , 4 ], [ 4 , 5 ], [ 5 , 2 ],
[ 2 , 6 ], [ 6 , 0 ]]
S = 0
T = 4
# To keep track of visited nodes
visited_array = list ( False for _ in range (N))
# If there exists a simple
# cycle between S & T
if (findSimpleCycle(cur = S, graph = createGraph(edges, N),
start = S, dest = T,
visited = visited_array,
flag = 0 )):
print ( "Yes" )
# If no simple cycle exists
# between S & T
else :
print ( "No" )
|
using System;
using System.Collections.Generic;
class Graph {
// Function to create graph
static void createGraph(List<List< int > > graph,
List<List< int > > edges)
{
foreach (List< int > x in edges)
{
// As it is an undirected graph
// so add an edge for both directions
graph[x[0]].Add(x[1]);
graph[x[1]].Add(x[0]);
}
}
static bool findSimpleCycle( int cur,
List<List< int > > graph,
int start, int dest,
bool [] visited, bool flag)
{
// After reaching T, change the dest to S
if (!flag && cur == dest) {
dest = start;
flag = true ;
}
// If S is reached without touching a
// node twice except S and T,
// then return true
if (flag && cur == dest) {
return true ;
}
bool ans = false ;
visited[cur] = true ;
foreach ( int child in graph[cur])
{
// A node can only be visited if it
// hasn't been visited or if it
// is S or t
if (!visited[child] || child == dest) {
ans = ans
| findSimpleCycle(child, graph, start,
dest, visited,
flag);
}
}
// Change visited of the current node
// to 0 while backtracking again so
// that all the paths can be traversed
visited[cur] = false ;
return ans;
}
public static void Main( string [] args)
{
int nodes = 7;
List<List< int > > edges = new List<List< int > >() {
new List< int >() { 0, 1 },
new List< int >() { 1, 2 },
new List< int >() { 2, 3 },
new List< int >() { 3, 4 },
new List< int >() { 4, 5 },
new List< int >() { 5, 2 },
new List< int >() { 2, 6 },
new List< int >() { 6, 0 }
};
int S = 0, T = 4;
// To store the graph
List<List< int > > graph = new List<List< int > >();
for ( int i = 0; i < nodes; i++) {
graph.Add( new List< int >());
}
// To keep track of visited nodes
bool [] visited = new bool [nodes];
createGraph(graph, edges);
// If there exists a simple
// cycle between S & T
if (findSimpleCycle(S, graph, S, T, visited,
false )) {
Console.WriteLine( "Yes" );
}
// If no simple cycle exists
// between S & T
else {
Console.WriteLine( "No" );
}
}
} |
<script> // Javascript program for the above approach // Function to create graph function createGraph(graph, edges) {
for (x of edges) {
// As it is an undirected graph
// so add an edge for both directions
graph[x[0]].push(x[1]);
graph[x[1]].push(x[0]);
}
} function findSimpleCycle(cur, graph, start, dest, visited, flag) {
// After reaching T, change the dest to S
if (!flag && cur == dest) {
dest = start;
flag = 1;
}
// If S is reached without touching a
// node twice except S and T,
// then return true
if (flag && cur == dest) {
return true ;
}
let ans = 0;
visited[cur] = 1;
for (child of graph[cur]) {
// A node can only be visited if it
// hasn't been visited or if it
// is S or t
if (!visited[child] || child == dest) {
ans = ans
| findSimpleCycle(
child, graph, start,
dest, visited, flag);
}
}
// Change visited of the current node
// to 0 while backtracking again so
// that all the paths can be traversed
visited[cur] = 0;
return ans;
} let nodes = 7; let edges = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 2], [2, 6], [6, 0]]; let S = 0, T = 4; // To store the graph let graph = new Array(nodes).fill(0).map(() => []);
// To keep track of visited nodes let visited = new Array(nodes);
createGraph(graph, edges); // If there exists a simple // cycle between S & T if (findSimpleCycle(S, graph,
S, T, visited, 0)) {
document.write( "Yes" );
} // If no simple cycle exists // between S & T else {
document.write( "No" );
} // This code is contributed by saurabh_jaiswal. </script> |
No
Time Complexity: O(N!). As we can see in this algorithm, all paths can be traversed, in the worst case, we are going to traverse all paths to find one that works, see this article: https://www.geeksforgeeks.org/count-possible-paths-two-vertices/amp/
Auxiliary Space: O(N^2)