您的位置:首页 > 其它

poj1737 Connected Graph

2015-09-21 22:46 155 查看
题目意思就不赘述了。

这是一个计数问题,一开始考虑如何去重却没有想到可行的办法。

原因是只考虑计数连通的方案数是困难的。

设n阶图连通的方案数为f(n),不连通的方案数为g(n) = 2^(2, n) - f(n)。

不连通的图存在多于1个的连通分量,而每个连通分量是连通的,这是本题的切入点。

考虑点1所在的连通分量,设其节点数为k(< n),那么所求即等价于计数剩余(n - k)个节点连通或不连通方案数。

可以枚举从1到n - 1枚举k,如此有g(n) = sigma((k - 1, n - 1) * f(k) * 2 ^ (2, n - k))。

根据此递推方程计算即可。

考虑到数值结果非常大,用java内置大数。

http://poj.org/problem?id=1737

package sample_java_project;

import java.math.BigInteger;
import java.util.Scanner;

public class myfirstjava{
public static BigInteger f[] = new BigInteger [55];
public static BigInteger c[][] = new BigInteger [55][55];
public static BigInteger power[] = new BigInteger [55];
public static void main(String[] args){
init();
int n;
Scanner cin = new Scanner(System.in);
while(cin.hasNext()){
n = cin.nextInt();
if(n == 0) break;
System.out.println(F(n));
}
}

public static void init(){
power[0] = BigInteger.ONE;
for(int i = 1; i < 51; i++) power[i] = power[i - 1].multiply(BigInteger.valueOf(2));
for(int i = 0; i < 55; i++) for(int j = 0; j < 55; j++) c[i][j] = BigInteger.valueOf(-1);
for(int i = 0; i < 55; i++) f[i] = BigInteger.valueOf(-1);
}

public static BigInteger C(int k, int num){
if(c[k][num] != BigInteger.valueOf(-1)) return c[k][num];
if(k > num) return BigInteger.ZERO;
if(k == 0 || k == num) return BigInteger.ONE;
return c[k][num] = C(k - 1, num - 1).add(C(k, num - 1));
}

public static BigInteger power(BigInteger num){
BigInteger ans = BigInteger.valueOf(1);
while(num != BigInteger.ZERO){
ans = ans.multiply(BigInteger.valueOf(2));
num = num.subtract(BigInteger.ONE);
}
return ans;
}

public static BigInteger F(int num){
if(f[num] != BigInteger.valueOf(-1)) return f[num];
BigInteger tem = BigInteger.ZERO;
for(int i = 1; i < num; i++)
tem = tem.add((F(i).multiply(power(C(2, num - i)))).multiply(C(i - 1, num - 1)));
return f[num] = power(C(2, num)).subtract(tem);
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: