题意:求 n 个点的无向简单带标号联通图个数。
记 f[n] 是所求答案,g[n] 是 n 个点的不联通图个数,f[n] + g[n] = h[n] = 2 ^ ((n*(n-1)/2)
设 1 所在联通块有 k 个点, 1<=k<n
Connected Graph
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2945 | Accepted: 1445 |
Description
An undirected graph is a set V of vertices and a set of E∈{V*V} edges.An undirected graph is connected if and only if for every pair (u,v) of vertices,u is reachable from v.
You are to write a program that tries to calculate the number of different connected undirected graph with n vertices.
For example,there are 4 different connected undirected graphs with 3 vertices.
You are to write a program that tries to calculate the number of different connected undirected graph with n vertices.
For example,there are 4 different connected undirected graphs with 3 vertices.

Input
The input contains several test cases. Each test case contains an integer n, denoting the number of vertices. You may assume that 1<=n<=50. The last test case is followed by one zero.
Output
For each test case output the answer on a single line.
Sample Input
1 2 3 4 0
Sample Output
1 1 4 38
Source
/**
* Created by OI_lover on 2015/4/9.
*/
import java.io.*;
import java.util.*;
import java.math.BigInteger;
import static java.math.BigInteger.*;
public class Main {
public static final int N = 55;
public static void main(String[] args) throws Exception
{
BigInteger []h = new BigInteger[N];
BigInteger []f = new BigInteger[N];
BigInteger []g = new BigInteger[N];
BigInteger p2[] = new BigInteger[N*N];
BigInteger [][]C = new BigInteger[N][N];
for (int i=0;i<N;i++)
{
for (int j=0;j<=i;j++)
{
if (i==j || j==0) C[i][j] = valueOf(1);
else C[i][j] = C[i-1][j-1].add(C[i-1][j]);
}
}
p2[0] = ONE;
for (int i=1;i<N*N;i++)
p2[i] = p2[i-1].multiply(valueOf(2));
for (int i=0;i<N;i++)
h[i] = p2[i*(i-1)/2];
f[1] = BigInteger.valueOf(1);
g[1] = BigInteger.valueOf(0);
for (int n=2;n<N;n++)
{
g[n] = BigInteger.ZERO;
for (int k = 1;k < n; k++)
{
BigInteger t = C[n-1][k-1].multiply(f[k]);
t = t.multiply(h[n-k]);
g[n] = g[n].add(t);
f[n] = h[n].subtract(g[n]);
}
}
Scanner in = new Scanner(System.in);
while (in.hasNext())
{
int n = in.nextInt();
if (n == 0) break;
System.out.println(f[n]);
}
}
}