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>
Output
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/dsa/count-possible-paths-two-vertices/
Auxiliary Space: O(N^2)

