POJ 1737 Connected Graph

本文提供了一种方法来计算给定点数的无向简单带标号联通图个数,涉及图论基础知识和组合数学应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:求 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. 

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]);
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值