光之大陆

题目求的就是点仙人掌的数量;点仙人掌的所有环缩点之后就变成了一棵树,于是考虑无根树的数量怎么求,很显然利用Prufer序列就好了;然后考虑怎么将Prufer序列移植到点仙人掌上面,此时就要利用扩展Prufer序列

扩展Prufer序列:对于一个点仙人掌来说,先将所有环缩点变成一棵树,然后将所有缩点离散化(就是重新编号),指定编号最大的为根;执行Prufer操作,首先选择一个度数为1的且编号最小的缩点,删除其,并向prufer序列中添加其与父亲的连边的另一端点(注意另一端点是原图上的点,不是缩点的编号),并重复以上的操作,如下

image

黑色是原图的编号,红色是缩点的编号;我们最开始选择缩点1,然后发现另一端是点3,于是prufer序列的第一个为3(不是2

由以上过程可知,如果我们知道了Prufer序列,有多少个缩点,每个点在哪个缩点内部,就可以唯一确定这个仙人掌;所以我们只需要解决以上三个问题就好了

有多少个缩点:枚举就好了,设有i个缩点,于是1in;为了方便,我们设点n所在的缩点编号为i(这样是为了不重复计数)

每个点在哪个缩点内部:利用递推解决。设f[i][j]表示将i个点分为j个缩点,并且每个缩点不是根(也就是说每个缩点都有父亲)的方案数。f[i][j]=k=0ij(i1k)(k+1)!2f[ik1][j1]
,这一式子的意义是:我们假设第j个缩点包含i,从1 ~ i1中选出k个点与i一起在缩点j中;考虑圆排列的个数是k!,由于翻转是同一种,所以总数即k!2,而缩点j是有父亲的,于是选择一个点与父亲相连,乘以k;最后剩下ik1个点分成j1个缩点(注意我们不的缩点大小要么是1,要么不低于3,也就是不能为2,至于为什么下面说)

Prufer序列的个数:这个比较简单,为ni2

最终的答案:ans=(n1)!2+i=2nj=0ni(n1j)j!2(j+1)f[nj1][i1]ni2
,这一式子的意义是:枚举缩点个数i,其中i包含n,再枚举j个点与n一起在缩点i中;由于考虑圆排列(去除对称)个数为j2,由于其没有父亲,所以不用乘j+1;然而在Prufer序列最后剩两个点的时候,唯一的一条边可以连接j+1个点中的任意一个,所以乘以j+1;再将剩下的n1j个点分为有父亲的i1个缩点,方案数为f[nj1][i1];最后乘以Prufer序列个数(注意这里也不能算大小为2的缩点)

不算大小为2的缩点的原因:会重复计数。比如下图

image

这个仙人掌既有可能在三个点单独为缩点的时候被统计,还有可能在相邻两个点为缩点,另一个点单独成为缩点的时候被统计

没看懂yxc那个代码的思路。。。

posted @   最爱丁珰  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示