CodeForces 11D(动态规划-状压dp)

以你之姓@ 2022-06-01 03:41 299阅读 0赞

问题描述:

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 mlines contains two integers a and b, (1 ≤ a, b ≤ n, a ≠ b) indicating that vertices aand 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.

Example

Input

  1. 4 6
  2. 1 2
  3. 1 3
  4. 1 4
  5. 2 3
  6. 2 4
  7. 3 4

Output

  1. 7

题目题意:求一个无向图环的个数

题目分析:dp[i][j]表示在i状态下,最后一个为节点j,能到达此状态的方式数,(我看了一些博客,有的人说保存的是环的个数,感觉不是特别妥,最简单的例子,初始化为1的时候,dp[1<<(i-1)][i]=1,不一定存在自环),如果存在一条路G[j][pos],pos为第一个节点,那么ans+=dp[i][j];

代码如下:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<cmath>
  5. #define ll long long
  6. using namespace std;
  7. const int maxn=20;
  8. bool G[maxn][maxn];
  9. ll dp[(1<<20)][maxn];
  10. bool check (int n)//节点个数大于等于3才行
  11. {
  12. int cnt=0;
  13. for (int i=1;i<=20;i++) {
  14. if (n&(1<<(i-1))) cnt++;
  15. }
  16. return cnt>=3;
  17. }
  18. int main()
  19. {
  20. int n,m;
  21. scanf("%d%d",&n,&m);
  22. memset (G,false,sizeof (G));
  23. memset (dp,0,sizeof (dp));
  24. for (int i=1;i<=m;i++) {
  25. int a,b;
  26. scanf("%d%d",&a,&b);
  27. G[a][b]=G[b][a]=true;
  28. }
  29. ll ans=0;
  30. for (int i=1;i<=n;i++) {
  31. dp[1<<(i-1)][i]=1;
  32. }
  33. for (int i=1;i<(1<<n);i++) {
  34. int pos=0;
  35. for (int l=1;l<=20;l++) {//找头
  36. if (i&(1<<(l-1))) {
  37. pos=l;
  38. break;
  39. }
  40. }
  41. for (int j=pos;j<=n;j++) {
  42. if (i&(1<<(j-1))) {
  43. for (int k=pos;k<=n;k++) {
  44. if (!(i&(1<<(k-1)))&&G[j][k]) {
  45. dp[i|(1<<(k-1))][k]+=dp[i][j];
  46. if (G[pos][k]&&check(i|(1<<(k-1)))) ans+=dp[i][j];
  47. }
  48. }
  49. }
  50. }
  51. }
  52. printf("%lld\n",ans/2);//重复了一半+
  53. return 0;
  54. }

发表评论

表情:
评论列表 (有 0 条评论,299人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Codeforces 1215E DP

    题意:给你一个序列,你可以交换序列中的相邻的两个元素,问最少需要交换多少次可以让这个序列变成若干个极大的颜色相同的子段。 思路:由于题目中的颜色种类很少,考虑状压DP。设dp

    相关 group dp

      应某些人要求,我把标签删掉了   这是一道好题。   一看$c<=16$果断状压,但是怎么压?   一个很显然的思路是,枚举上下两层的状态,每一层的状态极限有$C(c

    相关 POJ 1185(动态规划-dp)

    问题描述: 司令部的将军们打算在N\M的网格地图上部署他们的炮兵部队。一个N\M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),

    相关 HDU 5691(动态规划-dp)

    问题描述: 度度熊是他同时代中最伟大的数学家,一切数字都要听命于他。现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了。游戏的规则十分简单,参与游戏的N个整数将会做成一排