CF641G Little Artem and Graph 题解(DP ver.)
出题人以为自己出了神仙 dp 题然后被矩阵树定理杀穿了。提交记录全是矩阵树定理做法。无敌了。
为了体谅出题人,本篇题解来说说 dp 做法(绝对不是因为我不会矩阵树定理!)。
感觉是被低估的题目啊。
下文所说的
首先需要考虑树的性质。树的性质是有
你发现肯定是要对某种满足条件的加边序列进行计数,因为你很难直接维护树的结构。
考虑如何去重,我们分批次加边,每条边在两个端点中标号较大的点加入,将每个点加入的边集记录下来作为生成树的代表元。容易发现这样的方案唯一对应了一颗生成树。

例如这张图可以在每个节点加入这些边得到一颗生成树:
仔细观察这张图,发现每次加点都会构成一个大小
考虑和最新点连边的


例如这两张图,从蓝色团中删除了
我们如果把一个团看成一个点,可以感觉这大致构成了一个树的结构,因为你每次相当于是把一个点附加在原来的
例如,可以将第一张图转化成这个树(团的编号是团中最大节点的编号)

因此可以考虑从树形 dp 的角度去想。
然而,节点和节点之间的答案并不是完全独立的,这之间还有
换句话说,我们需要记录这
例如,要编码这张图的联通状态: 
就可以用这个序列来表示:
从子树转移到时候,我们先花
- 确保最后一个点和至少一个其它点是联通的,因为这个点之后不会再有连边了。
- 加边之后不会产生环。
之后把最后一个点删掉,对状态重新编号并且和父节点合并,合并时也需要注意不能产生环。
对于
实现方面,开始时只有
虽然这个题目开了
有以下几个常数优化技巧:
- 将状态压缩成
unsigned int,每位存放一个数。 - 预处理状态的合并结果,转移时查表或者合并是缓存结果。
- 预处理
种合并结果,转移时查表。
代码在这里。