zoukankan      html  css  js  c++  java
  • 图论--连通图计数模板

    问题:含有n个不同的点的连通图有多少种,即同构的图算是多个。

    记 含有n个点的连通图个数为 F[n] ;

      含有n个点的不连通图个数为 G[n] ;

      含有n个点的图的个数为 H[n] = 2^(n*(n-1)/2) ;

      有  F[n] + G[n] = H[n] ;  F[n] = H[n] - G[n] ;

    因此要求 F[n] 只需求 G[n] ;

    求 G[n] :枚举 1 号点所在的连通块大小为 k ( 1 ~ n-1 ) ;

         当 1 号点所在连通块大小为 k 时: k个点选取情况为组合数  C[n-1][k-1]

                         该连通块的种类数确定 k 个点后,连通块的种类数为 F[k] 

                         剩余 n-k 个点组成的图的种类数 H[n-k]

                         因此情况数为 C[n-1][k-1] * F[k] * H[n-k]

         G[n]为所有枚举的情况数总和  Σ( k : 1 ~ n-1 ) ( C[n-1][k-1] * F[k] * H[n-k] )

    定初始值 F[1] = 1 , G[1] = 1

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<math.h>
     5 using namespace std;
     6 typedef long long ll;
     7 
     8 const int maxn=1e3+5;
     9 const int mod=1e9+7;
    10 
    11 ll C[maxn][maxn];        //组合数
    12 ll F[maxn],G[maxn],H[maxn];
    13 
    14 ll QP(ll a,ll n){        //快速幂
    15     ll tmp=a,ans=1;
    16     while(n){
    17         if(n&1)ans=ans*tmp%mod;
    18         tmp=tmp*tmp%mod;
    19         n>>=1;
    20     }
    21     return ans;
    22 }
    23 
    24 void init(){
    25     for(int i=1;i<maxn;++i)H[i]=QP(2,i*(ll)(i-1)/2);
    26     for(int i=0;i<maxn;++i){
    27         for(int j=0;j<=i;++j){
    28             C[i][j]=(i&&j)?(C[i-1][j]+C[i-1][j-1])%mod:1;
    29         }
    30     }
    31     F[1]=1;G[1]=1;
    32     for(int i=2;i<maxn;++i){
    33         G[i]=0;
    34         for(int k=1;k<i;++k){
    35             G[i]=(G[i]+C[i-1][k-1]*F[k]%mod*H[i-k]%mod)%mod;
    36         }
    37         F[i]=((H[i]-G[i])%mod+mod)%mod;
    38     }
    39 }
  • 相关阅读:
    [ PyQt入门教程 ] Qt Designer工具的使用
    [ PyQt入门教程 ] PyQt5开发环境搭建和配置
    Notepad++提升工作效率小技巧
    思考:测试人员如何快速成长
    Linux /tmp目录下执行脚本失败提示Permission denied
    使用Quartz实现定时任务
    算法篇(前序)——Java的集合
    深入理解 JVM(上)
    Linux集锦
    秒杀系统实现高并发的优化
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/5688338.html
Copyright © 2011-2022 走看看