codeforces 724F. Uniformly Branched Trees
来源:互联网 发布:知乎怎样匿名回答 编辑:程序博客网 时间:2024/06/06 10:04
题目链接:http://codeforces.com/problemset/problem/724/F
题目大意:给定三个数n,d,mod,求有多少种n个点的不同构的树满足:除了度数为1的结点外,其余结点的度数均为d。答案对质数mod取模。
数据范围:1 ≤ n ≤ 1000, 2 ≤ d ≤ 10, 10^8 ≤ mod ≤ 10^9
题解:看到题目不难想到是树形dp。首先我们考虑有根树,f[i][j][k]表示有 i 个结点,根结点有 j 棵子树,每棵子树大小不超过k的方案数。有两种情况:
1.所有的子树大小都小于k,转移到f[i][j][k-1]。
2.有 l (l>0)棵子树大小为k,结果应为f[i-l*k][j-l][k-1]*C(f[k][d-1][k-1]+l-1,l)。注:C(X+l-1,l)表示从X种方案中选取 l 种,可以重复。
求出了有根树的方案数,我们需要转化成无根树。上述方案会重复计算答案的值,是因为同一棵树选取不同的结点作根时在 f 中表现出的状态是不同的,所以我们应该找到一个特殊的结点作为根,即树的重心,因为树的重心只有一个或两个。我们知道,对于一棵树的重心,它的子树大小不会超过n/2,所以答案为f[n][d][n/2]。而当一棵树有两个重心时,说明这棵树的重心的最大子树恰好有n/2(n为偶数)个点,此时应该减去重复(即两个重心在 f 中表示的状态不同时)的方案数C(f[n/2][d-1][n/2],2)。
最后,当n<=2时没有度数为d的点,此时特判一下就可以了。
时间复杂度O(n^2*d^2)
代码如下:
#include <algorithm>#include <cstdio>int f[1005][11][1005],g[1005][11],ine[11],n,d,mo;int inv(int x){ int i=1,y=mo-2; for (;y;y>>=1,x=1ll*x*x%mo) if (y&1) i=1ll*i*x%mo; return i;}int main(){ scanf("%d%d%d\n",&n,&d,&mo); for (int i=0;i<=n;i++) f[1][0][i]=1; for (int i=1;i<=d;i++) g[1][i]=1; for (int i=1;i<=d;i++) ine[i]=inv(i); for (int i=2;i<=n;i++) { for (int j=1;j<=d;j++) { for (int k=1;k<i;k++) for (int l=1;l<=j && l*k<=i;l++) f[i][j][k]=(f[i][j][k]+1ll*f[i-l*k][j-l][k-1]*g[k][l])%mo; for (int k=1;k<=n;k++) f[i][j][k]=(f[i][j][k]+f[i][j][k-1])%mo; } g[i][1]=f[i][d-1][n]; for (int j=2;j<=d;j++) g[i][j]=1ll*g[i][j-1]*(f[i][d-1][n]+j-1)%mo*ine[j]%mo; } int ans; if (n<=2) ans=1; else ans=f[n][d][n/2]; if (n>2 && !(n&1)) ans=(ans-1ll*(f[n/2][d-1][n/2]-1)*f[n/2][d-1][n/2]%mo*ine[2]%mo+mo)%mo; printf("%d\n",ans);}
0 0
- codeforces 724F. Uniformly Branched Trees
- Trees CodeForces
- Codeforces 659F F
- codeforces C.Coloring Trees
- codeforces C. Coloring Trees
- Trees ——CodeForces
- Codeforces 234 F. Fence
- 【Codeforces 500F】Dp
- codeforces 234F - Fence
- F-Logo Turtle codeforces
- 【CODEFORCES】 F. Ant colony
- Codeforces 567F
- CodeForces 241F Race
- Codeforces 611F 思维
- Codeforces 542F 构造
- codeforces 626f
- codeforces 622f
- codeforces 628F
- 191.Maximum Product Subarray-乘积最大子序列(中等题)
- Linux使用tcpdump抓获取WIFI包
- 在低版本浏览器,open()用get方法时出现乱码
- datasnap越用越慢原因
- Chrome控制台技巧秘籍:[5]拾取网页颜色编码
- codeforces 724F. Uniformly Branched Trees
- 偶然间收藏了以为网友的java总结分享,写的非常好,记录一下。
- HDU-1233-还是畅通工程
- UVa156
- [机器学习] Coursera笔记 - 机器学习应用的建议-Part1
- 穿透肌肤
- Linux进程间的通信方式----消息队列
- Android ListView setEmptyView
- [CodeForces725 C. Hidden Word] 构造 + STL