📜  在无向图中打印所有哈密顿循环

📅  最后修改于: 2021-10-25 03:13:29             🧑  作者: Mango

给定一个由大小为N*N的邻接矩阵graph[][]形式的N 个节点组成的无向图,任务是在给定的无向图中打印所有可能的哈密顿循环(以起始顶点为“0”)。

例子:

方法:给定的问题可以通过使用回溯生成所有可能的哈密顿循环来解决。请按照以下步骤解决问题:

  • 创建一个辅助数组,比如path[]来存储节点的遍历顺序,以及一个布尔数组visited[]来跟踪当前路径中包含的顶点。
  • 最初,将顶点(在本例中为“0”)添加到path
  • 现在,递归地将顶点一一添加到路径中以找到循环。
  • 在将顶点添加到path之前,请检查正在考虑的顶点是否与先前添加的顶点相邻并且不在path 中。如果找到这样的顶点,则将其添加到路径中,并在visited[]数组中将其值标记为true
  • 如果路径的长度等于N ,并且从路径中的最后一个顶点到0有一条边,则打印路径数组。
  • 完成上述步骤后,如果不存在这样的路径,则打印No Hamiltonian Cycle possible

下面是上述方法的实现:

Java
// 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 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 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 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);
    }
}


输出:
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

时间复杂度: O(N!)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程