Connected Graph

Connected Graph

Seeking n points undirected FIG Unicom number, \ (n \ Leq 50 \) .

solution

FIG do no direct link to the state equal to the edge points is considered to do, it is difficult to weight, i.e. not considering the opposite Unicom Unicom.

Difficult to determine the total number of programs is n points \ (2 ^ {\ FRAC {n \ Times (. 1-n)} {2}} \) , so arranged \ (F_i \) indicates n points undirected The number of connected graph, we have

\[f_i=2^{\frac{n(n-1)}{2}}-\sum_{j=1}^{i-1}f_jC_i^j2^{\frac{(i-j)(i-j-1)}{2}}\]

But such a transfer duplicate, to consider re-specialization, noting that if this picture is not legitimate, may be equivalent to a connected graph any illegal, so can not legally force the point 1, it is

\[f_i=2^{\frac{n(n-1)}{2}}-\sum_{j=1}^{i-1}f_jC_{i-1}^{j-1}2^{\frac{(i-j)(i-j-1)}{2}}\]

Border: \ (f_1 = 1 \)

The answer: \ (F_n \)

Obviously time complexity \ (O (^ n-2) \) , but it takes up a lot of time with high accuracy.

Reference Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define ll long long
using namespace std;
struct lll{
    int num[1001];
    lll(){num[0]=1;}
    il void clear(){
        memset(num,0,sizeof(num)),num[0]=1;
    }
    il void read(){
        string s;cin>>s,num[0]=s.size();
        for(ri int i(1);i<=num[0];++i)
            num[i]=s[num[0]-i];
    }
    il void print(){
        for(ri int i(num[0]);i;--i)putchar(num[i]+48);
    }
    il void operator=(string s){
        num[0]=s.size();
        for(ri int i(1);i<=s.size();++i)
            num[i]=num[s.size()-i];
    }
    il lll operator+(lll x){
        lll y;y.clear();ri int i;
        for(i=1;i<=num[0]||i<=x.num[0];++i){
            y.num[i]+=num[i]+x.num[i];
            if(y.num[i]>9)++y.num[i+1],y.num[i]-=10;
        }y.num[0]=i;
        while(!y.num[y.num[0]]&&y.num[0]>1)--y.num[0];
        return y;
    }
    il lll operator-(lll x){
        lll y;y.clear();ri int i;
        for(i=1;i<=num[0];++i){
            y.num[i]+=num[i]-x.num[i];
            if(y.num[i]<0)--y.num[i+1],y.num[i]+=10;
        }y.num[0]=i;
        while(!y.num[y.num[0]]&&y.num[0]>1)--y.num[0];
        return y;
    }
    il lll operator*(lll x){
        lll y;y.clear();ri int i,j,k;
        for(i=1;i<=num[0];++i){
            k=0;
            for(j=1;j<=x.num[0];++j)
                y.num[i+j-1]+=num[i]*x.num[j]+k,
                    k=y.num[i+j-1]/10,y.num[i+j-1]%=10;
            y.num[i+x.num[0]]+=k;
        }y.num[0]=i+j;
        while(!y.num[y.num[0]]&&y.num[0]>1)--y.num[0];
        return y;
    }
}p2[2501],c[51][51],dp[51];
int main(){
    int n,i,j;p2[0]="1";
    for(i=1;i<=2500;++i)p2[i]=p2[i-1]+p2[i-1];
    for(i=0;i<=50;++i){c[i][0]="1";
        for(j=1;j<=i;++j)
            c[i][j]=c[i-1][j]+c[i-1][j-1];
    }
    while(scanf("%d",&n),n){
        memset(dp,0,sizeof(dp)),dp[1]="1";
        for(i=2;i<=n;++i){
            dp[i]=p2[i*(i-1)>>1];
            for(j=1;j<i;++j)
                dp[i]=dp[i]-dp[j]*c[i-1][j-1]*p2[(i-j)*(i-1-j)>>1];
        }dp[n].print(),putchar('\n');
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/a1b3c7d9/p/10987557.html