ZJOI2018

线图(状态压缩,dp,搜索,树的最小表示法)

观察样例。先模拟一下求线图的过程。

观察,发现原图上的每一个边数$<=k$的连通块都代表了线图上的几个点。且每一种连通块代表的点的个数一样,都为图的$k$阶线图的代表点的个数。

所以问题就转化成了:算出每种不同构的有根树,计算每个有根树的权重,计算每个有根树在原图内出现的次数。

算出每种有根树可以使用括号序列+最小表示法。可以先枚举一下树的括号序列,再用最小表示法去重。

树的最小表示法就是字典序最小的括号序列('('比')'小)。生成这个序列的方式是:dfs当前节点x的所有子树,得到子树的最小表示序列。把这个序列按照字典序排序,从小到大拼起来,在左边+'(',在右边加')'就得到了以x节点为根的树的最小表示法。判定两棵树是否同构,只要判定它的最小表示法序列是否相同即可。

接下来是计算权重。初始的权重是这棵树的$k$阶线图的点数。但是这并不是真正的权重,内部包含了这棵树的导出子图的贡献,要减去。

显然暴力展开是不行的。可以推出$k=1~4$的公式。然后把$L_k(G)$视为$L_4(L_{k-4}(G))$,暴力展开后使用公式计算。

公式如下:

(咕咕咕)

计算出现的次数可以使用dp。设$f[i][j]$表示当前点i匹配情况为j的答案。设一个辅助数组g表示计算前面几个树的答案。

转移时,先把f[i]复制到g,用f[son][k]更新g[j],再把g复制给f[i]

还有一个问题:现在我们强行把树有标号化了。如果子树重复要除掉重复数的阶乘。

历史

迷宫

保镖

猜你喜欢

转载自www.cnblogs.com/cszmc2004/p/12337283.html