图论--连通二分图计数

问题:含有两边分别为 n 和 m 个不同的点的连通二分图有多少种,即同构的图算是多个。

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

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

  含有 n , m 个点的图的个数为 H[n][m] = 2^(n*m) ;

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

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

求 G[n][m] :枚举 1 号点所在的连通块大小为 k1 ( 1 ~ n ) + k2 ( 0 ~ m ) 且 k1、k2 不能同时取最大值;

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

                          k2个点选取情况为组合数  C[m][k2]

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

                          剩余 n-k1 + m-k2 个点组成的图的种类数 H[n-k1][m-k2]

                          因此情况数为 C[n-1][k1-1] * C[m][k2] * F[k1][k2] * H[n-k1][m-k2]

     G[n]为所有枚举的情况数总和

定初始值 F[0][0] = F[0][1] = F[1][0] = 1 , 其余有一维是 0 时 F 值为 0

 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=55;
 9 const int maxm=55;
10 const int mod=1e9+7;
11 
12 ll C[maxn][maxn];        //组合数
13 ll F[maxn][maxm],G[maxn][maxm],H[maxn][maxm];
14 
15 ll QP(ll a,ll n){        //快速幂
16     ll tmp=a,ans=1;
17     while(n){
18         if(n&1)ans=ans*tmp%mod;
19         tmp=tmp*tmp%mod;
20         n>>=1;
21     }
22     return ans;
23 }
24 
25 void init(){
26     for(int i=0;i<maxn;++i){
27         for(int j=0;j<maxm;++j){
28             H[i][j]=QP(2,i*j);
29         }
30     }
31     for(int i=0;i<maxn;++i){
32         for(int j=0;j<=i;++j){
33             C[i][j]=(i&&j)?(C[i-1][j]+C[i-1][j-1])%mod:1;
34         }
35     }
36     F[0][0]=F[1][0]=F[1][0]=1;
37     for(int i=2;i<maxn;++i)F[i][0]=0;
38     for(int i=2;i<maxm;++i)F[0][i]=0;
39     for(int i=1;i<maxn;++i){
40         for(int j=1;j<maxm;++j){
41             G[i][j]=0;
42             for(int k1=1;k1<=i;++k1){
43                 for(int k2=0;k2<=j;++k2){
44                     if(k1==i&&k2==j)continue;
45                     G[i][j]+=C[i-1][k1-1]*C[j][k2]%mod*F[k1][k2]%mod*H[i-k1][j-k2]%mod;
46                     G[i][j]%=mod;
47                 }
48             }
49             F[i][j]=((H[i][j]-G[i][j])%mod+mod)%mod;
50         }
51     }
52 }
原文地址:https://www.cnblogs.com/cenariusxz/p/5688549.html