zoukankan      html  css  js  c++  java
  • 【POJ 1737】Connected Graph

    Connected Graph
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 3010   Accepted: 1481

    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

     
    教主的题目。
    第一题应该是相对其它题来说较简单的了吧。
    其实在刘汝佳的书上有提到过。
    设f(n)为答案,g(n)则为有n个顶点的不连通图的个数,h(n)是总方案数。
    很明显,对于h(n)我们可以直接求出,因为每一条边有两种情况,一共有n*(n-1)/2条边,所以 f(n) + g(n) = h(n) = 2n*(n-1)/2
    然后我们要求出g(n)是多少。选择一个点作为中心,假设是V1,那么和V1在一起成为一个连通块的方案数是 sum{C(n-1,i-1)*f(i)*h(n-i)},这个式子表示n个点除了V1外的点,要拿出i-1个顶点和V1凑成i个点的连通图的方案数,当然,根据乘法原理,除了这i个点以外的n-i个点有h(n-i)种情况,所以要两个结果相乘。
    最坑爹的是用十进制的高精度会超时,我们要用万进制来节省时间。这个算法的时间复杂度是O(N2)(除高精度外)。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    struct BigInt
    {
        static const int BASE = 10000;
        int s[1000];
        int len;
    
        BigInt()
        {
            memset(s, 0, sizeof(s));
            len = 0;
            s[len++] = 0;
        }
        
        BigInt operator = (const int &b)
        {
            memset(s, 0, sizeof(s));
            len = 0;
            s[len++] = b;
            int i = 0;
            while (s[i] > BASE)
            {
                s[len++] = (s[i] / BASE);
                s[i] %= BASE;
            }
            return (*this);
        }
    
        BigInt operator + (const int &b)
        {
            s[0] += b;
            for (int i = 1; i < len; ++i)
            {
                s[i] += s[i - 1] / BASE;
                s[i - 1] %= BASE;
            }
            if (s[len - 1] > BASE)
            {
                s[len] = s[len - 1] / BASE;
                s[len - 1] %= BASE;
                len++;
            }
            return (*this);
        }
        
        BigInt operator + (const BigInt &b) const
        {
            BigInt c;
            c.len = max(b.len, len);
            for (int i = 0; i < c.len; ++i)
            {
                c.s[i] += s[i] + b.s[i];
                c.s[i + 1] += c.s[i] / BASE;
                c.s[i] %= BASE;
            }
            while (c.s[c.len])
            {
                c.s[c.len + 1] = c.s[c.len] / BASE;
                c.s[c.len++] %= BASE;
            }
            return c;
        }
    
        BigInt operator * (int x)
        {
            for (int i = 0; i < len; ++i) s[i] *= x;
            for (int i = 0; i < len; ++i)
            {
                s[i + 1] += s[i] / BASE;
                s[i] %= BASE;
            }
            while (s[len])
            {
                s[len + 1] = s[len] / BASE;
                s[len++] %= BASE;
            }
            return (*this);
        }
    
        BigInt operator * (const BigInt &b) const
        {
            BigInt c;
            int x, m;
            for (int i = 0; i < b.len; ++i)
            {
                x = 0;
                for (int j = 0; j < len; ++j)
                {
                    c.s[i + j] += x + b.s[i] * s[j];
                    x = c.s[i + j] / BASE;
                    c.s[i + j] %= BASE;
                }
                c.s[i + len] += x;
            }
            c.len = b.len + len;
            while (c.len > 1 && c.s[c.len - 1] == 0) c.len--;
            while (c.s[c.len])
            {
                c.s[c.len + 1] = c.s[c.len] / BASE;
                c.s[c.len] %= BASE;
            }
            return c;
        }
    
        BigInt operator - (const BigInt &b)
        {
            BigInt c;
            memcpy(c.s, s, sizeof(s));
            c.len = len;
            for (int i = 0; i < b.len; ++i)
            {
                c.s[i] = c.s[i] - b.s[i];
                if (c.s[i] < 0)
                {
                    c.s[i] = BASE + c.s[i];
                    c.s[i + 1]--;
                }
            }
            while (c.len > 1 && c.s[c.len - 1] == 0) c.len--;
            return c;
        }
    
        BigInt operator / (const int &b) const
        {
            BigInt c;
            c = 0;
            int x = 0;
            for (int i = len - 1; i >= 0; --i)
            {
                x = x * BASE + s[i];
                if (x >= b)
                {
                    c = c * BASE + x / b;
                    x %= b;
                }
                else c = c * BASE;
            }
            return c;
        }
        
    };
    
    const int MAXN = 55;
    
    BigInt h[MAXN], g[MAXN], f[MAXN];
    int n;
    
    BigInt C(int m, int k)
    {
        BigInt ans;
        ans = 1;
        for (int i = m - k + 1; i <= m; ++i) ans = ans * i;
        for (int i = 1; i <= k; ++i) ans = ans / i;
        return ans; 
    }
    
    int main()
    {
        h[0] = 1;
        h[1] = 1;
        f[1] = 1;
        g[1] = 0;
        for (int i = 2; i <= 50; ++i)
        {
            h[i] = 1;
            for (int j = 0; j < i * (i - 1) / 2; ++j) h[i] = h[i] * 2;
            for (int j = 1; j < i; ++j)
                g[i] = g[i] + (C(i - 1, j - 1) * f[j] * h[i - j]);
            f[i] = h[i] - g[i];
        }
        while (scanf("%d", &n) == 1 && n)
        {
            printf("%d", f[n].s[f[n].len - 1]);
            for (int i = f[n].len - 2; i >= 0; --i) printf("%04d", f[n].s[i]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    lamp
    ssh 交互脚本
    mysql 备份检测主从脚本
    RANDOM 猜数字脚本
    ansible+playbook 搭建lnmp环境
    集群搭建
    grafana
    nginx lnmp搭建
    shell 基础(1): 变量
    seq 增量输出命令
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4767875.html
Copyright © 2011-2022 走看看