題意
求個點,不超過條割邊的有標號圖個數。
題解
調得懷疑人生了,總算A了。。。
設個點的圖個數爲,個點連通圖個數爲,個點強連通圖個數爲,個點條割邊的連通圖個數爲,則答案可以由數組求出。
顯然有
求需要一個輔助數組,代表有個點,把另外個點劃分成一些連通塊,每個連通塊向這個點連邊的方案數,
則
求需要一個輔助數組,代表有個點,可以在個點之間連邊或者把它們和剩下個點連邊,有條割邊的方案數,
則
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define IN inline
#define R register int
const int N=55;
const ll p=1000000007;
int n,k;
ll e[N],c[N][N],l[N],g[N],G[N][N],f[N][N],F[N][N][N],ans[N][N],S;
IN ll add(ll a,ll b){return a+b<p?a+b:a+b-p;}
IN ll sub(ll a,ll b){return a-b<0?a-b+p:a-b;}
IN ll mul(ll a,ll b){return a*b%p;}
IN ll expo(ll a,int b){
static ll c;c=1;
while(b){
if(b&1)c=c*a%p;
b>>=1; a=a*a%p;
}
return c;
}
int main(){
scanf("%d%d",&n,&k);
for(R i=1;i<=n;i++)e[i]=expo(2,(i*(i-1))>>1);
for(R i=0;i<=n;i++)c[i][0]=1;
for(R i=1;i<=n;i++)for(R j=1;j<=i;j++)c[i][j]=add(c[i-1][j],c[i-1][j-1]);
for(R i=1;i<=n;i++){
l[i]=e[i];
for(R j=1;j<i;j++)l[i]=sub(l[i],mul(mul(c[i-1][j-1],e[i-j]),l[j]));
}
for(R k=1;k<=n;k++)G[k][0]=1;
for(R k=1;k<=n;k++)for(R i=1;i<=n-k;i++)for(R j=1;j<=i;j++)
G[k][i]=add(G[k][i],mul(mul(c[i-1][j-1],j*k),mul(l[j],G[k][i-j])));
g[0]=1;
for(R i=1;i<=n;i++){
g[i]=l[i];
for(R j=1;j<i;j++)g[i]=sub(g[i],mul(mul(c[i-1][j-1],G[j][i-j]),g[j]));
}
for(R i=1;i<=n;i++)F[i][0][0]=1;
for(R i=1;i<=n;i++){
f[i][0]=g[i];
for(R j=1;j<i;j++)for(R k=1;k<i;k++)
f[i][j]=add(f[i][j],mul(mul(c[i-1][k-1],g[k]),F[k][j][i-k]));
for(R k=1;k<=n-i;k++)for(R j=0;j<i+k;j++)
for(R I=1;I<=i;I++)for(R J=0;J<j;J++)
F[k][j][i]=add(F[k][j][i],mul(mul( c[i-1][I-1],mul(f[I][J],k*I) ),F[k][j-J-1][i-I]));
}
ans[0][0]=1;
for(R i=1;i<=n;i++)for(R j=0;j<=i;j++)
for(R I=1;I<=i;I++)for(R J=0;J<=j;J++)ans[i][j]=add(ans[i][j],mul(c[i-1][I-1],mul(f[I][J],ans[i-I][j-J])));
for(R i=0;i<=k;i++)S=add(S,ans[n][i]);
printf("%lld",S);
return 0;
}