背景
这把报了 UnRated 从 E 开始看,于是非常惨烈的只拿下了 E。
这个 2054 难度的题居然只有绿。
E - Replace
题意
给你两个字符串 \(s,t\),你每次可以把 \(s\) 中的一种字符换成另一种,求把 \(s\) 变成 \(t\) 的最小操作数,可能无解。
思路
我们先考虑无解怎么判:可以得到无解的一个充分不必要条件是 \(s\) 串中存在一个字符,他需要变成多种字符,这种情况显然无解。
于是我们记录一个 \(com\) 数组,\(com_i\) 表示字符 \(i\) 需要变成什么字符,如果不在 \(s\) 串中出现 计为 \(com_i=0\),否则即使该字符要变成其本身,也得记录 \(com_i=i\)。
之后我们考虑建图,我们从 \(i \to com_i\) 连一条有向边,如果 \(com_i=0\) 则不连,这样构成的图一定是个由树和内向基环树祖成的图。
我们先考虑 \(ans\) 一定大于等于什么,很显然是需要改变的字符数量。
之后我们考虑对于中间的环,而非自环而言,有两类情况:
- 只由一个独立的环构成,如图:
我们把这种环叫做 第一类环,这种情况我们需要找一个空节点(不在当前的 \(s\) 串中出现的字符)来辅助他(样例 \(4\)),我们可以先将环上任意一个节点变为该辅助节点,之后按顺序变,之后在将辅助节点变回来,代价为环长 \(+1\),下面是口胡的样例 \(4\) 解释:
abac
xbxc
xbxa
xcxa
bcba
那么问题来了,如果我们找不到辅助节点,那就无解,如练成一个长度为 \(26\) 的环,这也无解。
- 这个环外面有与其直接相连的
那我们可以把要变成 \(a\) 的都集中到不在环上的,这样我们就多出来一个可以用来辅助别的环的点,这样我们所需要的代价是联通块长。
那么现在问题来了:如何通过操作造出来一个可以辅助第一类环的点,那么像第二类的环,就可以造出来一个这样的点,我们把这样的点叫做空闲点。
我们注意到如果本身就一个在 \(s\) 串中未出现的字符 \(i\),即 \(com_i=0\),这张图本身就有空闲点。而如果这单纯只是一个自环,那么这个自环造不出空闲点,反之,我们提前把要变成形成自环的那个字符的字符,先变成其要变的字符,这样我们就多出来一个空闲点,而代价不增加。
总结
我们需要做如下事情:
- 建图,并判断第一类无解。
- 找环。
- 判断是否需要空闲点,即找有无第一类环。
- 按上述过程造空闲点,不需要则无所谓。
- 如果需要空闲点,但造不出来,则无解。
- 反之则有解,对于每个一类环,额外算一个贡献。
- 答案为需要改变的符号加上上一步算的额外贡献。
最终代码:Submission-64367352