给你N个点和M条边,求当中包含的简单路径的个数。
网上看的题解,其实就是求哈密顿回路数,但是是无向图而且至少由三个点组成。
http://codeforces.com/blog/entry/337
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const ll maxm=1<<19;
ll dp[maxm][20],sum;
int lowbit[maxm];
bool map[20][20];
int n,m,u,v,start;
inline bool bt(int i,int mask)
{
return mask&(1<<i);
}
inline int cnt(int mask)
{
int ret=0;
while(mask) ret+=(mask&1),mask>>=1;
return ret;
}
void getfirst()
{
int i;
for(i=1; i<maxm; i++)
{
int mask=i,ret=0;
while(mask&1^1) ret++,mask>>=1;
lowbit[i]=ret;
}
}
ll dfs(int mask,int end)
{
int j,tmp=cnt(mask);
ll ans=0;
if(dp[mask][end]>=0) return dp[mask][end];
for(j=start; j<n; j++)
if(j!=end&&bt(j,mask)&&map[j][end]&&(tmp==2||j!=start))
ans+=dfs(mask^(1<<end),j);
if(tmp>2&&map[end][start])//当前搜索的end点和起始点相连并且含有3个点以上
sum+=ans;
return dp[mask][end]=ans;
}
int main()
{
int i;
getfirst();
memset(dp,-1,sizeof(dp));
memset(map,0,sizeof(map));
cin>>n>>m;
sum=0;
while(m--)
{
cin>>u>>v;
u--,v--;
map[u][v]=map[v][u]=1;
}
for(i=0; i<n; i++) dp[1<<i][i]=1;
int maxmask=1<<n;
for(int mask=0; mask<maxmask; mask++)
if(cnt(mask)>1)
{
start=lowbit[mask];
for(i=start; i<n; i++)
if(bt(i,mask)&&map[start][i])
dfs(mask,i);
}
cout<<sum/2<<endl;
return 0;
}