S(n)表示n个点的图的个数
我们每新加一个点n,它与前面的点有2^(n-1)种连法(就是与前面每个点连还是不连)
根据乘法原理 S(n)=2n*(n-1)/2
f(n)表示n个点,每个点都和点1相连,且n个点互相连通的图的个数
g(n)表示n个点,每个点都和点1相连,且不是n个点互相连通的图的个数。
f(n)=S(n)−g(n)
从除了1之外的n-1个点中选出i-1个点,让这i个点互相连通,而剩下的n-i个点和这i个点没有边相连,互相之间随意连接。
https://www.luogu.com.cn/problem/T133184
//求由编号为 1~n的点构成的无向连通图的数量 #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,p=1000000009; ll f[1005],C[1005][1005],ex[1005]; ll qpow(ll a,ll b){ ll ans=1; while(b){ if(b&1)ans=ans*a%p; a=a*a%p; b>>=1; } return ans; } int main(){ scanf("%d",&n); f[1]=1;f[2]=1; for(int i=0;i<=n;i++){ C[i][0]=1; for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%p; } ex[0]=1; for(int i=1;i<=n;i++)ex[i]=qpow(2,i*(i-1)/2); for(int i=3;i<=n;i++){ f[i]=ex[i]; for(int j=1;j<=i-1;j++) f[i]=(f[i]-f[j]*C[i-1][j-1]%p*ex[i-j]%p+p)%p; } printf("%lld ",f[n]); return 0; }