Codeforces Beta Round #11 D. A Simple Task(状压DP)

来源:互联网 发布:问道手游辅助软件 编辑:程序博客网 时间:2024/05/22 01:29
Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices or edges.InputThe 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.OutputOutput the number of cycles in the given graph.Examplesinput4 61 21 31 42 32 43 4output7NoteThe 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 20using 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;}





0 0
原创粉丝点击