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


  • 相关阅读:
    好用的软件记录
    微信小程序 设计理念指南
    开启Python之路
    升级到iOS9之后的相关适配
    ARC模式下的内存泄露问题
    Git 源代码管理工具
    SVN版本控制系统
    单例 singleton
    双击改变图片大小和多点触摸改变图片大小
    循环引用 -- id 为什么是 assign 而不是 retain
  • 原文地址:https://www.cnblogs.com/chilumanxi/p/5136086.html
Copyright © 2011-2022 走看看