Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices or edges.
Input
The first line of input contains two integers n and m (1 ≤ n ≤ 19, 0 ≤ m) – respectively the number of vertices and edges of the graph. Each of the subsequent m lines contains two integers a and b, (1 ≤ a, b ≤ n, a ≠ b) indicating that vertices a and b are connected by an undirected edge. There is no more than one edge connecting any pair of vertices.
Output
Output the number of cycles in the given graph.
Examples
input
4 6
1 2
1 3
1 4
2 3
2 4
3 4
output
7
Note
The example graph is a clique and contains four cycles of length 3 and three cycles of length 4.
分析:求简单环个数,n很小,但是爆搜是不行的。。因为结果是阶乘级别的,考虑状压dp,f[i][s][t]表示当前链中点的集合为i,起点为s终点为t的所有方案数,因为s,t必定属于i,而且一个简单环有多重表示方法,所以我们考虑精简状态,f[i][t]表示起点s 为 i 中编号最小点,终点为t的所有链方案数,最后如果edg(s,t)存在就将f[i][t]记入答案,因为环上每点有两个相邻点,所以最后答案要除以二。
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<queue>
#define INF 2147483640
#define eps 1e-9
#define MAXN 0x3f
#define N 20
using namespace std;
int n,m,u,v,fh[1<<19];
unsigned long long ans,dp[1<<19][N];
bool edg[N][N];
int f(int x)
{
return 1<<(x-1);
}
int main()
{
cin>>n>>m;
for(int i = 1;i <= n;i++) fh[f(i)] = i;
for(int i = 1;i <= m;i++)
{
cin>>u>>v;
edg[u][v] = edg[v][u] = true;
}
for(int i = 1;i <= (1<<n)-1;i++)
for(int t = fh[i & (-i)] + 1;t <= n;t++)
if(f(t) & i)
{
int s = fh[i & (-i)],sta = i - f(t) - f(s);
if(!sta)
{
dp[i][t] = edg[s][t];
continue;
}
for(int j = sta;j;j -= j & (-j))
if(edg[fh[j & (-j)]][t])
dp[i][t] += dp[i - f(t)][fh[j & (-j)]];
if(edg[s][t]) ans += dp[i][t];
}
cout<<ans/2<<endl;
}