首先,对于幂等函数,我们先随便找一个数 \( x \),假设 \( f(x) = c \),那么根据题目中的定义 \( f(f(x)) = f(x) = c \),即 \( f(c) = c \)。而 \( f(c) = c \) 显然也满足幂等函数的条件。
如果我们将其在图上表示,将 \( i \) 与 \( a_i \) 连接,那么这张图上所有点必须满足:要么这个点的出边指向自己(也就是自环),要么这个点的出边指向一个自环的点。然后我们要求将原本的图变为满足这个要求的图的最小代价。
在赛时,我将这个条件理解为 2-SAT,也就是如果当前点不是自环点,那么下一个点必须是自环点。但是因为还要求最小代价,所以直接用不太行。当时是想到用网络流来优化一下,但是看到数据范围也不太可行。
于是接下来继续挖掘条件,容易看出原本的图是一棵基环树。如果没有环,对于普通树来说,其实就类似于“没有上司的舞会”这道题。接下来继续考虑多了一个环该怎么处理。在环上,两个连续的点至少有一个是自环点,因此至多只有两种情况,实质上两个都是自环点的情况一定被包含在其中一个点一定是自环的情况。即 \( x \) 是自环点,那么 \( a_x \) 可以任意处理,反之同理。
到了这一步,接下来就是代码实现的问题,只需要找到环,然后在环上随便找两个相邻点,钦定其中一个为自环点进行树形 DP 即可。