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