zoukankan      html  css  js  c++  java
  • hihoCoder-1087 Hamiltonian Cycle (记忆化搜索)

    描述

    Given a directed graph containing n vertice (numbered from 1 to n) and m edges. Can you tell us how many different Hamiltonian Cycles are there in this graph?

    A Hamiltonian Cycle is a cycle that starts from some vertex, visits each vertex (except for the start vertex) exactly once, and finally ends at the start vertex.

    Two Hamiltonian Cycles C1, C2 are different if and only if there exists some vertex i that, the next vertex of vertex i in C1 is different from the next vertex of vertex i in C2.

    输入

    The first line contains two integers n and m. 2 <= n <= 12, 1 <= m <= 200.

    Then follows m line. Each line contains two different integers a and b, indicating there is an directed edge from vertex a to vertex b.

    输出

    Output an integer in a single line -- the number of different Hamiltonian Cycles in this graph.

    提示

    额外的样例:

    样例输入 样例输出
    3 3
    1 2               
    2 1              
    1 3
    0



    样例输入

    4 7
    1 2
    2 3
    3 4
    4 1
    1 3
    4 2
    2 1

    样例输出

    2

    题目大意:给一张无向图,找出哈密顿回路的条数。
    题目分析:暴搜,不过搜起来要讲究技巧,用二进制数表示状态结合记忆化搜索才能不超时。

    小技巧:sta&(-sta)便可得到只有二进制数sta最右边的1构成的数,如12&(-12)=8(负数在计算机内用反码表示)。


    代码如下:
    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    int n,m,dp[12][1<<12],st[12],p[1<<12];
    int DP(int u,int s)
    {
        if(dp[u][s])
            return dp[u][s];
        if(!s)
            return dp[u][s]=st[u]&1;
        int rest=s&st[u];
        while(rest){
            int tp=rest&(-rest);
            dp[u][s]+=DP(p[tp],s-tp);
            rest-=tp;
        }
        return dp[u][s];
    }
    int main()
    {
        int a,b;
        while(~scanf("%d%d",&n,&m))
        {
            memset(st,0,sizeof(st));
            while(m--)
            {
                scanf("%d%d",&a,&b);
                st[a-1]|=(1<<(b-1));
            }
            for(int i=0;i<n;++i)
                p[1<<i]=i;
            memset(dp,0,sizeof(dp));
            printf("%d
    ",DP(0,(1<<n)-2));
        }
        return 0;
    }
    

      

  • 相关阅读:
    HDFS命令操作和高可用
    nginx-nginx和反向代理概念
    day01 Hadoop 简单介绍及架构设计
    常用正则表达式
    【JavaWeb笔记】第二章 JDBC
    【JavaSE笔记】第二章 进制数据类型和运算符
    LeetCode-94 Binary Tree Inorder Traversal Solution (with Java)
    LeetCode-1019 Next Greater Node In Linked List Solution (with Java)
    LeetCode-946 Validate Stack Sequences Solution (with Java)
    LeetCode-739 Daily Temperatures Solution (with Java)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4820530.html
Copyright © 2011-2022 走看看