zoukankan      html  css  js  c++  java
  • 【51nod】1634 刚体图

    【51nod】1634 刚体图

    给一个左边n个点右边m个点二分图求合法的连通图个数,每条边选了之后会带来价值乘2的贡献

    类似城市规划那道题的计数

    (g[i][j])为左边(i)个点,右边(j)个点的图有多少个(就是边随便连)

    (f[i][j])为左边(i)个点右边(j)个点的连通图有多少个

    然后枚举和左边第一个点连通的联通块是几个左边点,几个右边点

    答案可以认为是

    (f[i][j] = g[i][j] - sum_{k = 0}^{i - 1}sum_{h = 0}^{j} inom{i - 1}{k}inom{j}{h} f[i - k][j - h] imes g[k][h])

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define ba 47
    #define MAXN 1000005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 1000000007;
    int N,M;
    int f[15][15],g[15][15],C[105][105];
    int fac[15],invfac[15];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    void update(int &x,int y) {
        x = inc(x,y);
    }
    int fpow(int x,int c) {
        int res = 1,t = x;
        while(c) {
    	if(c & 1) res = mul(res,t);
    	t = mul(t,t);
    	c >>= 1;
        }
        return res;
    }
    int main(){
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        for(int i = 0 ; i <= 100 ; ++i) {
    	C[i][0] = 1;
    	for(int j = 1 ; j <= i ; ++j) {
    	    C[i][j] = inc(C[i - 1][j],C[i - 1][j - 1]);
    	}
        }
        for(int i = 0 ; i <= 10 ; ++i) {
    	for(int j = 0 ; j <= 10 ; ++j) {
    	    for(int k = 0 ; k <= i * j ; ++k) {
    		update(g[i][j],mul(C[i * j][k],fpow(2,k)));
    	    }
    	}
        }
        
        
        while(scanf("%d%d",&N,&M) != EOF) {
    	memset(f,0,sizeof(f));
    	for(int i = 1 ; i <= N ; ++i) {
    	    for(int j = 0 ; j <= M ; ++j) {
    		f[i][j] = g[i][j];
    		for(int k = 0 ; k < i ; ++k) {
    		    for(int h = 0 ;h <= j ; ++h) {
    			if(!(h + k)) continue;
    			int c = mul(C[j][h],C[i - 1][k]);
    			c = mul(c,mul(f[i - k][j - h],g[k][h]));
    			update(f[i][j],MOD - c);
    		    }
    		}
    	    }
    	}
    	out(f[N][M]);enter;
        }
        return 0;
    }
    
  • 相关阅读:
    Android中Java反射技术的使用示例
    汉语-词语-念佛:百科
    汉语-词语-纯净:百科
    汉语-词语-具足戒:百科
    汉语-词语-比丘:百科
    汉语-词语-无常:百科
    汉语-词语-脱离:百科
    袁氏-人物-佛学-袁焕仙:百科
    汉语-词语-无量:百科
    汉语-词语-中观:百科
  • 原文地址:https://www.cnblogs.com/ivorysi/p/11075250.html
Copyright © 2011-2022 走看看