Description
要求构造一个 n 个节点的树使其满足以下三个条件:
1.树带标号,点的标号为
2.每个节点的度数不超过
3.树的最大匹配为 k
Input
两个整数
Output
输出满足条件的树的个数,结果模 109+7
Sample Input
2 1
Sample Output
1
Solution
把
1
节点看作根节点,那么问题变成构造最大匹配为
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=55;
#define mod 1000000007
#define inv2 500000004
int n,k,C[maxn][maxn],dp[maxn][maxn][2];
void add(int &x,int y)
{
x=x+y>=mod?x+y-mod:x+y;
}
int main()
{
C[0][0]=1;
for(int i=1;i<=50;i++)
{
C[i][0]=C[i][i]=1;
for(int j=1;j<i;j++)add(C[i][j],C[i-1][j-1]+C[i-1][j]);
}
scanf("%d%d",&n,&k);
if(k>n/2)printf("0\n");
else
{
dp[1][0][0]=dp[0][0][1]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=k;j++)
for(int l=0,r=i-1;l<=r;l++,r--)
for(int x=0;x<=j;x++)
{
int temp=1;
temp=C[i-1][l];
if(l==r)temp=(ll)temp*inv2%mod;
if(l)temp=(ll)temp*l%mod*r%mod;
else temp=(ll)temp*r%mod;
add(dp[i][j][0],(ll)dp[l][x][1]*dp[r][j-x][1]%mod*temp%mod);
if(x<j)
{
add(dp[i][j][1],(ll)dp[l][x][1]*dp[r][j-x-1][0]%mod*temp%mod);
add(dp[i][j][1],(ll)dp[l][x][0]*dp[r][j-x-1][1]%mod*temp%mod);
add(dp[i][j][1],(ll)dp[l][x][0]*dp[r][j-x-1][0]%mod*temp%mod);
}
}
printf("%d\n",(dp[n][k][0]+dp[n][k][1])%mod);
}
return 0;
}