poj1737(连通图计数)

链接:点击打开链接

题意:求n个点组成的连通图的种数

代码:

package poj1737;
import java.util.*;
import java.math.BigInteger;
public class Main{								//固定一个点,让0~N-2个点与这个点联通,剩下的点任意连
	public static void main(String[] args){		//总数是2^C(n,2),也就是完全图所有边数取还是不取
		BigInteger f[]=new BigInteger[2505];	//dp[i]为i个点的种数,则
		BigInteger dp[]=new BigInteger[55];		//dp[i]=2^C(i,2)-∑(j=1->n-1)(dp[j]*C(i-1,j-1)*2^(C(i-j,2)))
		BigInteger c[][]=new BigInteger[55][55];
		int n,i,j;
		BigInteger sum;
	    for(i=0;i<=50;i++)
	    dp[i]=BigInteger.valueOf(0);
	    f[0]=BigInteger.valueOf(1);
	    for(i=1;i<=2500;i++)					//因为大数没有pow因此先存起来
	    f[i]=f[i-1].multiply(BigInteger.valueOf(2));
	    dp[1]=BigInteger.valueOf(1);
	    for(i=1;i<=50;i++){
	        for(j=0;j<=i;j++){
	            if(j==0||j==i)
	            c[i][j]=BigInteger.valueOf(1);
	            else
	            c[i][j]=c[i-1][j].add(c[i-1][j-1]);
	        }
	    }
	    for(i=2;i<=50;i++){
	        sum=BigInteger.valueOf(0);
	        for(j=1;j<=i-1;j++)
	        sum=sum.add(dp[j].multiply(c[i-1][j-1]).multiply(f[(i-j)*(i-j-1)/2]));
	        dp[i]=f[i*(i-1)/2].subtract(sum);
	    }
	    Scanner cin=new Scanner(System.in);    
        while(cin.hasNext()){    
            n=cin.nextInt();    
            if(n==0) break;    
            System.out.println(dp[n]);    
        }  
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值