zoukankan      html  css  js  c++  java
  • 图论--连通二分图计数

    问题:含有两边分别为 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 }
  • 相关阅读:
    Rotation Kinematics
    离职 mark
    PnP 问题方程怎么列?
    DSO windowed optimization 代码 (4)
    Adjoint of SE(3)
    IMU 预积分推导
    DSO windowed optimization 代码 (3)
    DSO windowed optimization 代码 (2)
    OKVIS 代码框架
    DSO windowed optimization 代码 (1)
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/5688549.html
Copyright © 2011-2022 走看看