[南海云课堂] [SPFA] [二分答案] [巧妙转换] 单词串

· · 个人记录

题意

我们有 n 个字符串,每个字符串都是由 a∼z 的小写英文字母组成的。

如果字符串 A 的结尾两个字符刚好与字符串 B 的开头两个字符相匹配,那么我们称 AB 能够相连(注意:A 能与 B 相连不代表 B 能与 A 相连)。

我们希望从给定的字符串中找出一些,使得它们首尾相连形成一个环串(一个串首尾相连也算),我们想要使这个环串的平均长度最大。

如下例:

ababc bckjaca caahoynaab

第一个串能与第二个串相连,第二个串能与第三个串相连,第三个串能与第一个串相连,我们按照此顺序相连,便形成了一个环串,长度为 5+7+10=22(重复部分算两次),总共使用了 3 个串,所以平均长度是 223≈7.33

## 思路 * ### 歪解:缩点 无法保证百分百正确,不详讲。 观察题目,显然可以建边,又因为答案与环有关,因此考虑求强连通分量,在弹出栈这一步时计算答案即可。 但很容易被卡,因为题目要求平均值,而最大的均值不一定在极大强连通分量中。 而且这种做法很容易 $\rm{MLE}$,不要用为好。 ~~其实卡一卡就能过随机数据。~~ * ### 二分 + $\rm{SPFA}
首先我们发现,朴素建边不仅会爆空间还很麻烦,没有利用边权。

观察到前后缀共有 26^2 种不同形态,不妨将 前后缀 设为节点,字符串长度设为边权,这样将几种元素都很好地利用起来。例如:abac,我们就将 abac 连一条权为 4 的边。

其次,直接找遍历环很难实现。由复杂度理论知:判断性问题比直接做要简单,那不妨二分答案平均长度。

最后就是 check 函数了。平均长度 k 合法,当且仅当存在任意环使得 \frac {\sum\limits_{i=1}^{tot} {w_i}}{tot}\ge k。变式一下得:\sum\limits_{i=1}^{tot} wi\ge \sum\limits_{i=1}^{tot} k\to \sum\limits_{i=1}^{tot}(wi-k)\ge0

于是将每条边减去 k\rm{SPFA} 跑最长路判断是否存在正环即可。

代码

没有太多可说,主要是思路咋来的。