连通图计数模板【c++&Java】

来源:互联网 发布:js onclick事件传参 编辑:程序博客网 时间:2024/05/29 04:10

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

ll f[maxn];       //含n个点的连通图个数ll g[maxn];       //含n个点的不连通图个数ll h[maxn];       //含n个点的图的个数 h[n] = 2^(n*(n-1)/2)ll c[maxn][maxn]; //组合数/*f[n] = h[n]-g[n]要想求f[n],必须先求g[n]求g[n]g[n] = sum(k:1~n-1)(c[n-1][k-1]*f[k]*h[n-k])初始值:f[1] = g[1] = 1;c[m][n] = m!/(n!*(m-n)!)*/ll qpow(ll x,ll n){    ll res = 1;    while(n)    {        if(n&1)            res = res*x%mod;        x = x*x%mod;        n >>= 1;    }    return res;}void init(){    for(ll i = 1;i<maxn;i++)        h[i] = qpow(2,i*(i-1)/2);    for(int i=0;i<maxn;i++)    {        for(int j=0;j<=i;j++)        {            if(i&&j)                c[i][j] = (c[i-1][j]+c[i-1][j-1])%mod;            else                c[i][j] = 1;        }    }    f[1] = g[1] = 1;    for(int i=2;i<maxn;i++)    {        g[i] = 0;        for(int k = 1;k<i;k++)            g[i] = (g[i]+c[i-1][k-1]*f[k]%mod*h[i-k]%mod)%mod;        f[i] = ((h[i]-g[i])%mod+mod)%mod;    }}
import java.util.*;import java.math.*;public class Main {    static final int maxn = 105;    static BigInteger[] f = new BigInteger[maxn];    static BigInteger[] two = new BigInteger[maxn];    static BigInteger[] g = new BigInteger[maxn];    static BigInteger[] h = new BigInteger[maxn];    static BigInteger[][] c = new BigInteger[maxn][maxn];    static void init()    {        two[0] = BigInteger.ONE;        for(int i=1;i<maxn;i++)            two[i] = two[i-1].multiply(BigInteger.valueOf(2));        for(int i=1;i<maxn;i++)        {            int a = i;            int b = i-1;            if(a%2==0)                a/=2;            else                b/=2;            h[i] = BigInteger.ONE;            for(int j=0;j<a;j++)                h[i] = h[i].multiply(two[b]);        }        for(int i=0;i<maxn;i++)        {            for(int j=0;j<=i;j++)            {                if(i==j || j==0)                    c[i][j] = BigInteger.ONE;                else                    c[i][j] = c[i-1][j].add(c[i-1][j-1]);            }        }        f[1] = g[1] = BigInteger.ONE;        for(int i=2;i<maxn;i++)        {            g[i] = BigInteger.ZERO;            for(int k = 1;k<i;k++)                g[i] = g[i].add(c[i-1][k-1].multiply(f[k]).multiply(h[i-k]));            f[i] = h[i].subtract(g[i]);        }    }    public static void main(String[] args) {        init();        Scanner cin = new Scanner(System.in);        int n = cin.nextInt();        System.out.println(f[n]);        cin.close();    }}
0 0
原创粉丝点击