Print all Hamiltonian Cycles in an Undirected Graph

25 Oct, 2021
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}
{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 possibleExplanation: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++
Java
Python3
C#
Javascript
// C++ program for the above approach#include<bits/stdc++.h>using namespace std; // To check if there exists// at least 1 hamiltonian cyclebool hasCycle; // Function to check if a vertex v// can be added at index pos in// the Hamiltonian Cyclebool 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 cyclesvoid 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 cyclesvoid 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 Cycledef 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 cyclehasCycle = False # Function to find all possible# hamiltonian cyclesdef 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 cyclesdef 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 approachusing 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>
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)
suresh07
divyeshrabadiya07
divyesh072019
rameshtravel07
Graph Traversals
graph-connectivity
graph-cycle
Backtracking
Graph
Recursion
Recursion
Graph
Backtracking
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Find if there is a path of more than k length from a source
Find shortest safe route in a path with landmines
Longest Possible Route in a Matrix with Hurdles
Difference between Backtracking and Branch-N-Bound technique
Top 20 Backtracking Algorithm Interview Questions
Breadth First Search or BFS for a Graph
Depth First Search or DFS for a Graph
Dijkstra's shortest path algorithm | Greedy Algo-7
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Graph and its representations