题目描述
给定一棵n个点组成的有标号的树T,我们定义两棵有标号的树的相似度为它们共有的边的个数。
现在我们想知道,n个点的完全图所有的有标号的生成树中,有多少棵树与T的相似度为 0,1,2 … n - 1,答案对10^9+7取模
对于20%的数据,n <= 6。
对于40%的数据,n <= 15。
对于另外20%的数据,T中存在一个度数为n - 1的点。
对于100%的数据,2 <= n <= 100
解题思路
prufer 完全图,可以从prufer序角度考虑一下。
顺着暴力来:假如我们选出T的k条边,标记为必选,那么这个时候如果我们能快速知道此情况下生成树个数,那么就得到了相似度大于等于K的生成树的一些方案。统计所有情况,再容斥,就可以求出每一种相似度的答案了。
观察一下,此时联通块个数为n-k,设为m,若把联通块看成一个点,那么把联通块连起来的生成树的个数,由prufer序可知是 mm?2m m ? 2 个,然而一个联通块包含很多点,你在序列上填了一个联通块的编号,实际上可以是这个联通块里任意一个点,那么每个位置可以填1~n。另外,你不知道儿子联通块是哪个点连到父亲,最后剩下的两个联通块的边也没有确定时哪个点。那么方案数实际上是 nm?2?∏i=1..msize[i]n m ? 2 ? ∏ i = 1.. m s i z e [ i ] ,其中size[i]代表第i个联通块大小。
我们可以DP出对于每一个m,所有方案的 ∏i=1..msize[i]∏ i = 1.. m s i z e [ i ] 和。然后再乘上 nm?2n m ? 2 ,再容斥即可。注意到知道了联通块个数,就知道相似度了。
我们可以在T上树形DP,设f[i][j][k]表示i为根的子树,有j个联通块,其中i的联通块大小为k。那么对于一个x和他的儿子son,有两种转移。注意到i的联通块的k先不乘进去。
1,选择x-son的边, f‘[x][i+k?1][j+l]+=f[x][i][j]?f[son][k][l]f ‘ [ x ] [ i + k ? 1 ] [ j + l ] + = f [ x ] [ i ] [ j ] ? f [ s o n ] [ k ] [ l ]
2,不选, f′[x][i+k][j]+=f[x][i][j]?f[son][k][l]?lf ′ [ x ] [ i + k ] [ j ] + = f [ x ] [ i ] [ j ] ? f [ s o n ] [ k ] [ l ] ? l
最后的容斥就随便搞搞组合数就行了。
时间复杂度上界是 O(n4)O ( n 4 )
矩阵树定理 仍从暴力出发,在完全图中,我们枚举可能选的T的K条边,然后屏蔽掉剩下的T的边,在基尔霍夫矩阵上随便搞一个余子式,即可求出剩下的图的生成树个数。此时,求出的是相似度至多为K的方案。
考虑带权生成树计数的做法,此时我们的基尔霍夫矩阵不再是度数矩阵减邻接矩阵,而是边权和矩阵减去边权矩阵。这里一颗生成树的贡献是边权的乘积。
类似的,对于T的边,标记其为变量x。仍然对他求行列式,可以得出一个多项式,发现多项式i次项的系数,就是相似度为i时的生成树方案。
由于不能暴力求含未知数的行列式,我们带n个常数进去算,然后得出点值再拉格朗日插值回来,也可以算出答案。
时间复杂度严格 O(n4)O ( n 4 )
代码
【DP|[矩阵树定理][prufer序][CF917D]Stranger Trees】只有第一种做法的代码。
#include
#include
#include
#include
#include
推荐阅读
- 题目|C. Ayoub and Lost Array(思维dp)
- HDU 5185 Equation (DP)
- dp|AC Challenge(状态压缩DP)
- 题解|【HNOI2017】大佬-dalao
- CodeForces - 1282B2 B2. K for the Price of One (Hard Version)
- 经典题|3462: DZY Loves Math II
- Android|【常用工具类】DensityUtils(dp px 互相转换)