# CodeForces 11D A Simple Task （DP解哈密顿路径数目）

time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 ≤ 190 ≤ 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 ≤ na ≠ 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.

Sample test(s)
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.

dp[i][j]表示状态为i时，以j结尾的路径条数。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 205
#define MAXN 100005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

ll n,m,ans,flag,cnt,tot;
ll mp[20][20],dp[1<<19][19];

int first(int s)
{
for(int i=0;i<n;i++)
{
if(s&(1<<i)) return i;
}
}
void solve()
{
ll i,j,t,k,p,u,v,s;
ans=0;
tot=(1<<n)-1;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
dp[1<<i][i]=1;
}
for(i=1; i<=tot; i++)
{
for(j=0; j<n; j++)
{
if(dp[i][j]==0) continue ;
p=first(i);
for(k=p; k<n; k++)
{
if(j==k||mp[j][k]==0) continue ;
if(i&(1<<k))
{
if(k==p) ans+=dp[i][j];
}
else
{
s=i|(1<<k);
dp[s][k]+=dp[i][j];
}
}
}
}
ans-=m;
ans/=2;
printf("%I64d\n",ans);
}
int main()
{
ll i,j,t;
while(~scanf("%I64d%I64d",&n,&m))
{
memset(mp,0,sizeof(mp));
ll u,v;
for(i=1; i<=m; i++)
{
scanf("%I64d%I64d",&u,&v);
u--,v--;
mp[u][v]=mp[v][u]=1;
}
solve();
}
return 0;
}


• 评论

• 上一篇
• 下一篇