Given an undirected Graph consisting of N nodes in the form of an adjacency matrix graph[][] of size N*N, the task is to print all Hamiltonian cycles possible in the given undirected Graph (taking starting vertex as '0').
A Hamiltonian cycle (or Hamiltonian circuit) is a Hamiltonian Path such that there is an edge (in the graph) from the last vertex to the first vertex of the Hamiltonian Path.
Examples:
Input: graph[][] = {{0, 1, 1, 0, 0, 1}, {1, 0, 1, 0, 1, 1}, {1, 1, 0, 1, 0, 0}, {0, 0, 1, 0, 1, 0}, {0, 1, 0, 1, 0, 1}, {1, 1, 0, 0, 1, 0}}
Output:
0 1 2 3 4 5 0
0 1 5 4 3 2 0
0 2 3 4 1 5 0
0 2 3 4 5 1 0
0 5 1 4 3 2 0
0 5 4 3 2 1 0
Explanation:
All Possible Hamiltonian Cycles for the following graph (with the starting vertex as 0) are
- {0 ? 1 ? 2 ? 3 ? 4 ? 5 ? 0}
- {0 ? 1 ? 5 ? 4 ? 3 ? 2 ? 0}
- {0 ? 2 ? 3 ? 4 ? 1 ? 5 ? 0}
- {0 ? 2 ? 3 ? 4 ? 5 ? 1 ? 0}
- {0 ? 5 ? 1 ? 4 ? 3 ? 2 ? 0}
- {0 ? 5 ? 4 ? 3 ? 2 ? 1 ? 0}
Input: graph[][] = {{0, 1, 0, 1, 1, 0, 0}, {1, 0, 1, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 0, 1}, {1, 0, 1, 0, 0, 1, 0}, {1, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 1, 1, 0, 1}, {0, 0, 1, 0, 0, 1, 0}}
Output: No Hamiltonian Cycle possible
Explanation:
For the given graph, no Hamiltonian Cycle is possible:
Approach: The given problem can be solved by using Backtracking to generate all possible Hamiltonian Cycles. Follow the steps below to solve the problem:
- Create an auxiliary array, say path[] to store the order of traversal of nodes and a boolean array visited[] to keep track of vertices included in the current path.
- Initially, add the source vertex (in this case '0') to the path.
- Now, recursively add vertices to path one by one to find the cycle.
- Before adding a vertex to path, check whether the vertex being considered is adjacent to the previously added vertex or not and is not already in path. If such a vertex is found, then add it to the path and mark its value as true in the visited[] array.
- If the length of path becomes equal to N, and there is an edge from the last vertex in path to 0, then print the path array.
- After completing the above steps, if there exists no such path, then print No Hamiltonian Cycle possible.
Below is the implementation of the above approach:
// C++ program for the above approach
#include<bits/stdc++.h>
using namespace std;
// To check if there exists
// at least 1 hamiltonian cycle
bool hasCycle;
// Function to check if a vertex v
// can be added at index pos in
// the Hamiltonian Cycle
bool isSafe(int v, int graph[][6], vector<int> path, int pos)
{
// If the vertex is adjacent to
// the vertex of the previously
// added vertex
if (graph[path[pos - 1]][v] == 0)
return false;
// If the vertex has already
// been included in the path
for (int i = 0; i < pos; i++)
if (path[i] == v)
return false;
// Both the above conditions are
// not true, return true
return true;
}
// Recursive function to find all
// hamiltonian cycles
void FindHamCycle(int graph[][6], int pos, vector<int> path, bool visited[], int N)
{
// If all vertices are included
// in Hamiltonian Cycle
if (pos == N) {
// If there is an edge
// from the last vertex to
// the source vertex
if (graph[path[path.size() - 1]][path[0]] != 0) {
// Include source vertex
// into the path and
// print the path
path.push_back(0);
for (int i = 0; i < path.size(); i++) {
cout << path[i] << " ";
}
cout << endl;
// Remove the source
// vertex added
path.pop_back();
// Update the hasCycle
// as true
hasCycle = true;
}
return;
}
// Try different vertices
// as the next vertex
for (int v = 0; v < N; v++) {
// Check if this vertex can
// be added to Cycle
if (isSafe(v, graph, path, pos) && !visited[v]) {
path.push_back(v);
visited[v] = true;
// Recur to construct
// rest of the path
FindHamCycle(graph, pos + 1, path, visited, N);
// Remove current vertex
// from path and process
// other vertices
visited[v] = false;
path.pop_back();
}
}
}
// Function to find all possible
// hamiltonian cycles
void hamCycle(int graph[][6], int N)
{
// Initially value of boolean
// flag is false
hasCycle = false;
// Store the resultant path
vector<int> path;
path.push_back(0);
// Keeps the track of the
// visited vertices
bool visited[N];
for (int i = 0; i < N; i++)
visited[i] = false;
visited[0] = true;
// Function call to find all
// hamiltonian cycles
FindHamCycle(graph, 1, path, visited, N);
if (!hasCycle) {
// If no Hamiltonian Cycle
// is possible for the
// given graph
cout << "No Hamiltonian Cycle" << "possible " << endl;
return;
}
}
int main()
{
int graph[][6] = {
{ 0, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 1 },
{ 1, 1, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 1, 0, 1, 0, 1 },
{ 1, 1, 0, 0, 1, 0 },
};
hamCycle(graph, 6);
return 0;
}
// This code is contributed by rameshtravel07.
// Java program for the above approach
import java.util.ArrayList;
class GFG {
// Function to check if a vertex v
// can be added at index pos in
// the Hamiltonian Cycle
boolean isSafe(int v, int graph[][],
ArrayList<Integer> path,
int pos)
{
// If the vertex is adjacent to
// the vertex of the previously
// added vertex
if (graph[path.get(pos - 1)][v]
== 0)
return false;
// If the vertex has already
// been included in the path
for (int i = 0; i < pos; i++)
if (path.get(i) == v)
return false;
// Both the above conditions are
// not true, return true
return true;
}
// To check if there exists
// at least 1 hamiltonian cycle
boolean hasCycle;
// Function to find all possible
// hamiltonian cycles
void hamCycle(int graph[][])
{
// Initially value of boolean
// flag is false
hasCycle = false;
// Store the resultant path
ArrayList<Integer> path
= new ArrayList<>();
path.add(0);
// Keeps the track of the
// visited vertices
boolean[] visited
= new boolean[graph.length];
for (int i = 0;
i < visited.length; i++)
visited[i] = false;
visited[0] = true;
// Function call to find all
// hamiltonian cycles
FindHamCycle(graph, 1, path,
visited);
if (!hasCycle) {
// If no Hamiltonian Cycle
// is possible for the
// given graph
System.out.println(
"No Hamiltonian Cycle"
+ "possible ");
return;
}
}
// Recursive function to find all
// hamiltonian cycles
void FindHamCycle(int graph[][], int pos,
ArrayList<Integer> path,
boolean[] visited)
{
// If all vertices are included
// in Hamiltonian Cycle
if (pos == graph.length) {
// If there is an edge
// from the last vertex to
// the source vertex
if (graph[path.get(path.size() - 1)]
[path.get(0)]
!= 0) {
// Include source vertex
// into the path and
// print the path
path.add(0);
for (int i = 0;
i < path.size(); i++) {
System.out.print(
path.get(i) + " ");
}
System.out.println();
// Remove the source
// vertex added
path.remove(path.size() - 1);
// Update the hasCycle
// as true
hasCycle = true;
}
return;
}
// Try different vertices
// as the next vertex
for (int v = 0;
v < graph.length; v++) {
// Check if this vertex can
// be added to Cycle
if (isSafe(v, graph, path, pos)
&& !visited[v]) {
path.add(v);
visited[v] = true;
// Recur to construct
// rest of the path
FindHamCycle(
graph, pos + 1,
path, visited);
// Remove current vertex
// from path and process
// other vertices
visited[v] = false;
path.remove(
path.size() - 1);
}
}
}
// Driver Code
public static void main(String args[])
{
GFG hamiltonian = new GFG();
/* Input Graph:
(0) - - -- (2)
| \ / |
| (1) |
| / | |
| / | |
(5)----(4)--(3)*/
int[][] graph = {
{ 0, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 1 },
{ 1, 1, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 1, 0, 1, 0, 1 },
{ 1, 1, 0, 0, 1, 0 },
};
hamiltonian.hamCycle(graph);
}
}
# Python3 program for the above approach
# Function to check if a vertex v
# can be added at index pos in
# the Hamiltonian Cycle
def isSafe(v, graph, path, pos):
# If the vertex is adjacent to
# the vertex of the previously
# added vertex
if graph[path[pos - 1]][v] == 0:
return False
# If the vertex has already
# been included in the path
for i in range(pos):
if path[i] == v:
return False
# Both the above conditions are
# not true, return true
return True
# To check if there exists
# at least 1 hamiltonian cycle
hasCycle = False
# Function to find all possible
# hamiltonian cycles
def hamCycle(graph):
global hasCycle
# Initially value of boolean
# flag is false
hasCycle = False
# Store the resultant path
path = []
path.append(0)
# Keeps the track of the
# visited vertices
visited = [False]*(len(graph))
for i in range(len(visited)):
visited[i] = False
visited[0] = True
# Function call to find all
# hamiltonian cycles
FindHamCycle(graph, 1, path, visited)
if hasCycle:
# If no Hamiltonian Cycle
# is possible for the
# given graph
print("No Hamiltonian Cycle" + "possible ")
return
# Recursive function to find all
# hamiltonian cycles
def FindHamCycle(graph, pos, path, visited):
# If all vertices are included
# in Hamiltonian Cycle
if pos == len(graph):
# If there is an edge
# from the last vertex to
# the source vertex
if graph[path[-1]][path[0]] != 0:
# Include source vertex
# into the path and
# print the path
path.append(0)
for i in range(len(path)):
print(path[i], end = " ")
print()
# Remove the source
# vertex added
path.pop()
# Update the hasCycle
# as true
hasCycle = True
return
# Try different vertices
# as the next vertex
for v in range(len(graph)):
# Check if this vertex can
# be added to Cycle
if isSafe(v, graph, path, pos) and not visited[v]:
path.append(v)
visited[v] = True
# Recur to construct
# rest of the path
FindHamCycle(graph, pos + 1, path, visited)
# Remove current vertex
# from path and process
# other vertices
visited[v] = False
path.pop()
""" Input Graph:
(0) - - -- (2)
| \ / |
| (1) |
| / | |
| / | |
(5)----(4)--(3)"""
graph = [
[ 0, 1, 1, 0, 0, 1 ],
[ 1, 0, 1, 0, 1, 1 ],
[ 1, 1, 0, 1, 0, 0 ],
[ 0, 0, 1, 0, 1, 0 ],
[ 0, 1, 0, 1, 0, 1 ],
[ 1, 1, 0, 0, 1, 0 ],
]
hamCycle(graph)
# This code is contributed by divyesh072019.
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to check if a vertex v
// can be added at index pos in
// the Hamiltonian Cycle
static bool isSafe(int v, int[,] graph, List<int> path, int pos)
{
// If the vertex is adjacent to
// the vertex of the previously
// added vertex
if (graph[path[pos - 1],v] == 0)
return false;
// If the vertex has already
// been included in the path
for (int i = 0; i < pos; i++)
if (path[i] == v)
return false;
// Both the above conditions are
// not true, return true
return true;
}
// To check if there exists
// at least 1 hamiltonian cycle
static bool hasCycle;
// Function to find all possible
// hamiltonian cycles
static void hamCycle(int[,] graph)
{
// Initially value of boolean
// flag is false
hasCycle = false;
// Store the resultant path
List<int> path = new List<int>();
path.Add(0);
// Keeps the track of the
// visited vertices
bool[] visited = new bool[graph.GetLength(0)];
for (int i = 0; i < visited.Length; i++)
visited[i] = false;
visited[0] = true;
// Function call to find all
// hamiltonian cycles
FindHamCycle(graph, 1, path, visited);
if (!hasCycle) {
// If no Hamiltonian Cycle
// is possible for the
// given graph
Console.WriteLine("No Hamiltonian Cycle" + "possible ");
return;
}
}
// Recursive function to find all
// hamiltonian cycles
static void FindHamCycle(int[,] graph, int pos, List<int> path, bool[] visited)
{
// If all vertices are included
// in Hamiltonian Cycle
if (pos == graph.GetLength(0)) {
// If there is an edge
// from the last vertex to
// the source vertex
if (graph[path[path.Count - 1], path[0]] != 0) {
// Include source vertex
// into the path and
// print the path
path.Add(0);
for (int i = 0; i < path.Count; i++) {
Console.Write(path[i] + " ");
}
Console.WriteLine();
// Remove the source
// vertex added
path.RemoveAt(path.Count - 1);
// Update the hasCycle
// as true
hasCycle = true;
}
return;
}
// Try different vertices
// as the next vertex
for (int v = 0; v < graph.GetLength(0); v++) {
// Check if this vertex can
// be added to Cycle
if (isSafe(v, graph, path, pos) && !visited[v]) {
path.Add(v);
visited[v] = true;
// Recur to construct
// rest of the path
FindHamCycle(graph, pos + 1, path, visited);
// Remove current vertex
// from path and process
// other vertices
visited[v] = false;
path.RemoveAt(path.Count - 1);
}
}
}
static void Main() {
/* Input Graph:
(0) - - -- (2)
| \ / |
| (1) |
| / | |
| / | |
(5)----(4)--(3)*/
int[,] graph = {
{ 0, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 1 },
{ 1, 1, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 1, 0 },
{ 0, 1, 0, 1, 0, 1 },
{ 1, 1, 0, 0, 1, 0 },
};
hamCycle(graph);
}
}
// This code is contributed by suresh07.
<script>
// Javascript program for the above approach
// Function to check if a vertex v
// can be added at index pos in
// the Hamiltonian Cycle
function isSafe(v, graph, path, pos)
{
// If the vertex is adjacent to
// the vertex of the previously
// added vertex
if (graph[path[pos - 1]][v] == 0)
return false;
// If the vertex has already
// been included in the path
for (let i = 0; i < pos; i++)
if (path[i] == v)
return false;
// Both the above conditions are
// not true, return true
return true;
}
// To check if there exists
// at least 1 hamiltonian cycle
let hasCycle;
// Function to find all possible
// hamiltonian cycles
function hamCycle(graph)
{
// Initially value of boolean
// flag is false
hasCycle = false;
// Store the resultant path
let path = [];
path.push(0);
// Keeps the track of the
// visited vertices
let visited = new Array(graph.length);
for (let i = 0; i < visited.length; i++)
visited[i] = false;
visited[0] = true;
// Function call to find all
// hamiltonian cycles
FindHamCycle(graph, 1, path, visited);
if (!hasCycle) {
// If no Hamiltonian Cycle
// is possible for the
// given graph
document.write("No Hamiltonian Cycle" + "possible ");
return;
}
}
// Recursive function to find all
// hamiltonian cycles
function FindHamCycle(graph, pos, path, visited)
{
// If all vertices are included
// in Hamiltonian Cycle
if (pos == graph.length) {
// If there is an edge
// from the last vertex to
// the source vertex
if (graph[path[path.length - 1]][path[0]] != 0) {
// Include source vertex
// into the path and
// print the path
path.push(0);
for (let i = 0; i < path.length; i++) {
document.write(path[i] + " ");
}
document.write("</br>");
// Remove the source
// vertex added
path.pop();
// Update the hasCycle
// as true
hasCycle = true;
}
return;
}
// Try different vertices
// as the next vertex
for (let v = 0; v < graph.length; v++) {
// Check if this vertex can
// be added to Cycle
if (isSafe(v, graph, path, pos) && !visited[v]) {
path.push(v);
visited[v] = true;
// Recur to construct
// rest of the path
FindHamCycle(graph, pos + 1, path, visited);
// Remove current vertex
// from path and process
// other vertices
visited[v] = false;
path.pop();
}
}
}
/* Input Graph:
(0) - - -- (2)
| \ / |
| (1) |
| / | |
| / | |
(5)----(4)--(3)*/
let graph = [
[ 0, 1, 1, 0, 0, 1 ],
[ 1, 0, 1, 0, 1, 1 ],
[ 1, 1, 0, 1, 0, 0 ],
[ 0, 0, 1, 0, 1, 0 ],
[ 0, 1, 0, 1, 0, 1 ],
[ 1, 1, 0, 0, 1, 0 ],
];
hamCycle(graph);
// This code is contributed by divyeshrabadiya07.
</script>
Output:
0 1 2 3 4 5 0 0 1 5 4 3 2 0 0 2 3 4 1 5 0 0 2 3 4 5 1 0 0 5 1 4 3 2 0 0 5 4 3 2 1 0
Time Complexity: O(N!)
Auxiliary Space: O(N)