Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices or edges.
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 the number of cycles in the given graph.
4 6 1 2 1 3 1 4 2 3 2 4 3 4
7
The example graph is a clique and contains four cycles of length 3 and three cycles of length 4.
思路:转成计算有几条链能成环,限定链上最小的数字为起点,dp[i][j]为i状态下,以j为终点的链有几条,最后答案除二即可。
# include <bits/stdc++.h>
using namespace std;
int v[20][20]={0};
long long dp[1<<20][20]={0};
int main()
{
int n, m, st=0;
long long ans=0;
scanf("%d%d",&n,&m);
while(m--)
{
int a, b;
scanf("%d%d",&a,&b);
--a;--b;
v[a][b] = v[b][a] = 1;
}
for(int i=0; i<n; ++i) dp[1<<i][i] = 1;
for(int i=1; i<1<<n; ++i)
{
for(int j=0; j<n; ++j)
{
if(dp[i][j] == 0) continue;
for(int k=0; k<n; ++k)
{
if(i&(1<<k))
{
st = k;
break;
}
}
if(v[j][st] && __builtin_popcount(i)>2) ans += dp[i][j];
for(int k=st+1; k<n; ++k)
if(!(i&(1<<k)) && v[j][k]) dp[i|(1<<k)][k] += dp[i][j];
}
}
printf("%lld\n",ans/2);
return 0;
}