zoukankan      html  css  js  c++  java
  • hihoCoder 1087 Hamiltonian Cycle

    #1087 : Hamiltonian Cycle

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    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
    这是一个DP的题目,一开始只用DFS做的,但是实在是想不出来怎么考虑初始点的问题,即我们肯定以1为初始点,那么1的判重就是一个问题,如果把1一开始设置为重复的点,那么如果最后都遍历完以后如何回到1是个问题,如果将1特殊处理,那么在中途就有可能回到1点,也行不通,所以最后借鉴网上其他人对汉密尔顿回路的见解,从1点开始往后走,一直走到最后一个的时候判断他和1是否是相连的,同时对于状态的存储是依赖于一个DP数组,他的一维坐标是当前位置的下一个位置,而二维坐标是将已经保存的现在的走过的点的状态存储后转化成为unsigned long的值.这样就可以保存当前点到目标状态的方案数.


    代码如下:

    /*************************************************************************
    	> File Name: Hamiltionian_Cycle.cpp
    	> Author: Zhanghaoran0
    	> Mail: chiluamnxi@gmail.com
    	> Created Time: 2015年09月18日 星期五 21时21分17秒
     ************************************************************************/
    
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <bitset>
    #define OK 1
    #define ERROR 0
    using namespace std;
    
    int n ,m;
    int graph[210][210] = {0};
    int path[13];
    bitset<13> flag;
    
    int dp[13][100000];
    
    int dfs(int pos){
        if(pos == n + 1){
            if(graph[path[pos - 1]][path[1]])
                return OK;
            else 
                return ERROR;
        }
    
        int ans = 0;
        for(int x = 2; x <= n; x ++){
            if((!flag[x]) && graph[path[pos - 1]][x]){
                path[pos] = x;
                flag.set(x);
                if(dp[x][flag.to_ulong()] < 0)
                    dp[x][flag.to_ulong()] = dfs(pos + 1);
                ans += dp[x][flag.to_ulong()];
                flag.reset(x);
            }
        }
    
        return ans;
    }
    
    
    int main(void){
        int x, y;
        cin >> n >> m;
        for(int i = 0; i < m; i ++){
            cin >> x >> y;
            graph[x][y] = 1;
        }
    
        for(int i = 1; i <= n; i ++){
            path[i] = -1;
        }
    
        path[1] = 1;
        flag[1] = 1;
        memset(dp, -1, sizeof(dp));
        cout << dfs(2) << endl;
    
    }
    


  • 相关阅读:
    实验
    概率与期望
    2020CSP-S模板
    洛谷:P2538 [SCOI2008]城堡
    洛谷P1731 生日蛋糕
    洛谷 P1180 石子合并
    洛谷 P2831 愤怒的小鸟
    浅谈状压DP
    浅谈线段树
    LCA-树链剖分
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136086.html
Copyright © 2011-2022 走看看