【CF917D】Stranger Trees 树形DP+Prufer序列
【CF917D】Stranger Trees
题意:给你一棵n个点的树,对于k=1...n,问你有多少有标号的n个点的树,与给出的树有恰好k条边相同?
$n\le 100$
题解:我们先考虑容斥,求出和给出的树至少有k个点相同的树的数量。我们先选出原树中的k条边,然后剩下的边随便连。选出k条边后,原树被分成n-k个连通块,设其大小分别为$siz_1,siz_2...siz_{n-k}$。那么剩下的边随便连的方案数是多少呢?我们不妨把每个连通块看成一个点,答案变成n个点的完全图的生成树个数,根据Prufer序列知道这个答案是$n^{n-2}$。但是这里一个连通块的大小并不是1。对于一个大小为$siz$的连通块,如果它在Prufer序列中出现了j次,那么它对答案的贡献其实是$siz^{j+1}$(因为它的度数是j+1)。我们可以先把$\prod\limits_{i=1}^{n-k}siz_i$提出来,然后对于Prufer序列中的每个位置,如果它是第i个连通块,则贡献为$siz_i$,所以总的贡献为$\sum\limits_{i=1}^{n-k}siz_i=n$,那么答案就是$\prod\limits_{i=1}^{n-k}siz_i\times n^{n-k-2}$。
所以我们考虑树形DP,用f[x][a][b]表示在x的子树中,已经连了a条边,包含x的连通块大小为b的总贡献。最后容斥一发即可。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const ll P=1000000007;
int n,m,cnt;
int to[210],nxt[210],head[110],siz[110];
ll f[110][110][110],g[110][110],c[110][110],h[110],bt[110];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void dfs(int x,int fa)
{
f[x][1][0]=1,siz[x]=1;
for(int i=head[x],j,k,a,b,y;i!=-1;i=nxt[i]) if(to[i]!=fa)
{
y=to[i],dfs(to[i],x);
memset(g,0,sizeof(g));
for(j=1;j<=siz[x];j++) for(k=1;k<=siz[y];k++)
{
for(a=0;a<siz[x];a++) for(b=0;b<siz[y];b++)
{
g[j+k][a+b+1]=(g[j+k][a+b+1]+f[x][j][a]*f[y][k][b])%P;
g[j][a+b]=(g[j][a+b]+f[x][j][a]*f[y][k][b]%P*k)%P;
}
}
memcpy(f[x],g,sizeof(g));
siz[x]+=siz[y];
}
}
inline void add(int a,int b)
{
to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
}
int main()
{
n=rd();
int i,j,a,b;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
dfs(1,0);
for(bt[0]=i=1;i<=n;i++) bt[i]=bt[i-1]*n%P;
for(i=0;i<=n;i++) for(c[i][0]=j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
for(i=1;i<n;i++) for(j=0;j<n;j++) h[j]=(h[j]+f[1][i][j]*i)%P;
h[n-1]=1;
for(i=0;i<n-1;i++) h[i]=h[i]*bt[n-i-2]%P;
for(i=n-1;i>=0;i--)
{
for(j=i+1;j<n;j++) h[i]=(h[i]-c[j][i]*h[j])%P;
h[i]=(h[i]+P)%P;
}
for(i=0;i<n;i++) printf("%lld ",h[i]);
return 0;
}
【CF917D】Stranger Trees 树形DP+Prufer序列的更多相关文章
- CF917D Stranger Trees
		
CF917D Stranger Trees 题目描述 给定一个树,对于每个\(k=0,1\cdots n-1\),问有多少个生成树与给定树有\(k\)条边重合. 矩阵树定理+高斯消元 我们答案为\(f ...
 - hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)
		
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...
 - HDU 5629 Clarke and tree dp+prufer序列
		
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=562 题意: 求给每个节点的度数允许的最大值,让你求k个节点能组成的不同的生成树个数. 题解: 对于n ...
 - CF917D. Stranger Trees & TopCoder13369. TreeDistance(变元矩阵树定理+高斯消元)
		
题目链接 CF917D:https://codeforces.com/problemset/problem/917/D TopCoder13369:https://community.topcoder ...
 - Regionals 2014 >> Asia - Taichung 7003 - A Balance Game on Trees    树形DP + 二维费用背包
		
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
 - CF917D Stranger Trees【矩阵树定理,高斯消元】
		
题目链接:洛谷 题目大意:给定一个$n$个节点的树$T$,令$ans_k=\sum_{T'}[|T\cap T'|=k]$,即有$k$条边重合.输出$ans_0,ans_1,\ldots,ans_{n ...
 - [CF917D]Stranger Trees[矩阵树定理+解线性方程组]
		
题意 给你 \(n\) 个点的无向完全图,指定一棵树 \(S\),问有多少棵生成树和这棵树的公共边数量为 \(k\in[0,n-1]\) \(n\leq 100\) 分析 考虑矩阵树定理,把对应的树边 ...
 - HDU 4123 (2011 Asia FZU contest)(树形DP + 维护最长子序列)(bfs + 尺取法)
		
题意:告诉一张带权图,不存在环,存下每个点能够到的最大的距离,就是一个长度为n的序列,然后求出最大值-最小值不大于Q的最长子序列的长度. 做法1:两步,第一步是根据图计算出这个序列,大姐头用了树形DP ...
 - 5.13 省选模拟赛 优雅的绽放吧,墨染樱花 多项式 prufer序列 计数 dp
		
LINK:优雅的绽放吧,墨染樱花 当时考完只会50分的做法 最近做了某道题受到启发 故会做这道题目了.(末尾附30分 50分 100分code 看到度数容易想到prufer序列 考虑dp统计方案数. ...
 
随机推荐
- [转]MBProgressHUD 源码分析
			
源码来源: https://github.com/jdg/MBProgressHUD 版本:0.9.1 MBProgressHUD是一个显示HUD窗口的第三方类库,用于在执行一些后台任务时,在程序中显 ...
 - 【转】maven同时使用maven-surefire-report-plugin和maven-surefire-plugin默认将执行两次test
			
https://issues.apache.org/jira/browse/SUREFIRE-753 Here the pom.xml snippet how i configured the rep ...
 - 本地文件到通过flume到kafka
			
配置文件 cd /usr/app/flume1.6/conf vi flume-dirKakfa.properties #agent1 name agent1.sources=source1 agen ...
 - 和我一起学《HTTP权威指南》——连接管理
			
连接管理 1.TCP连接 几乎所有的HTTP通信都是由TCP/IP承载的. 浏览网页时客户端执行的操作: 如浏览http://www.joes-hardware.com:80/power-tools. ...
 - MVC使用 Elmah 日志记录组件
			
在后台管理中,有一些操作是需要增加操作日志的,尤其是对一些比较敏感的金额类的操作,比如商城类的修改商品金额.删除商品.赠送金额等人工的操作.日志中记录着相关操作人的操作信息,这样,出了问题也容易排查. ...
 - 图像中的artifacts
			
artifacts 瑕疵 伪影(Artifacts) 伪影(Artifacts)-CT-基础术语 - 影像园 http://www.xctmr.com/baike/ct/c34b5413e305b45 ...
 - char与TCHAR相互转换(拒绝中文乱码,好用!)
			
C++编程中屡屡要遇到宽窄字符转换的问题,尤其是字符串中有中文,稍有不慎就会中文乱码,程序运行出错. 下面为char*.char[]与TCHAR*.TCHAR[]互转的用法,不求花哨,只求好用!请参考 ...
 - 使用T4模板调用Sqlserver链接生成自己的模板
			
<#@ template debug="false" hostspecific="false" language="C#" #> ...
 - [转]WPF入口Application
			
1.WPF和 传统的WinForm 类似, WPF 同样需要一个 Application 来统领一些全局的行为和操作,并且每个 Domain (应用程序域)中只能有一个 Application 实例存 ...
 - 假设数组a有n个元素,元素取值范围是1~n,如何判定数组是否存在重复元素
			
方法一:位图法,原理是首先申请一个长度为n且均为’0’组成的字符串,字符串的下标即为数组a[]中的元素,然后从头开始遍历数组a[N],取每个数组元素的值,将其对应的字符串中的对应位置置1,如果已经置过 ...