b_vj_Hamiltonian Cycle(记忆化+位运算各种技巧)

给定一个有向图,求出该有向图中哈密顿回路的条数(哈密顿路径只关注经过的结点,不关注如何走的(也就是经过的边))

思路:暴搜

#include<iostream>
using namespace std;
const int N=13, M=1<<N;
int n,m,ans,ALL,nei[N],mp[M];
void dfs(int u, int s) { //u:当前访问结点,s:剩余未访问点集
    if (!s) {
        if ((nei[u]&1)==1) ans++; //需要判断原因是:如果此时如果图不是环路,s也为0,所以要判断是否u的下一个结点是否是起点0
        return;
    }
    int ns=s&nei[u]; //u结点下一步能访问的所有未使用结点(即未使用的结点与u的邻居的交集)
    while (ns) {
        int ts=ns&(-ns); //最右边的一位1(但ns&-ns的结果是一个十进制数,并不是编号,所以mp的作用就是映射)
        dfs(mp[ts],s^ts);
        ns=ns&(ns-1); //去掉最右边的一位1,ns^=ts也行
    }
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n>>m;
    for (int i=0; i<m; i++) {
        int u,v; cin>>u>>v, u--, v--;
        nei[u]|=(1<<v);
    }
    for (int i=0; i<n; i++) mp[1<<i]=i;
    ALL=1<<n;
    dfs(0,(ALL-1)^1);
    cout<<ans;
    return 0;
}

记忆化优化:

20143605--pcx/p/4820530.html
原文地址:https://www.cnblogs.com/wdt1/p/13961177.html