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;
    
    }
    


  • 相关阅读:
    装饰者模式
    NGUI研究院之三种方式监听NGUI的事件方法(七)
    unity3d连接数据库
    unity3d 连接MSSql
    Unity3D之游戏架构脚本该如何来写
    WCF 部署问题 小总结 (HTTP 不能注册的解决方法)
    Prototype
    web.config文件之自定义错误节
    asp:DropDownList与asp:DataList的联合使用
    剑指offer --合并链表
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136086.html
Copyright © 2011-2022 走看看