Tarjan
想当年高中组织活动的时候我还专门写过 Tarjan 的流程和证明,如今已经忘的干干净净,原来的代码也找不到了,只能现写了。
总的来说就是利用一个栈,将每个访问到的点 push 入栈,在寻找的过程中记录两个值,一个是 dfn—— 它是第几个搜索到的,一个是 low—— 它能衍生的点中 dfn 最小的值。如果一个点 dfn==low 说明它本身就是最小的点,把它及它栈以上的点全部 pop 出来就行,因为它上面的点必定是与它形成强联通分量。我们不妨假设它上面的点有不是它强联通分量的,那么此点在回溯到它本身的时候只有两种情况,一是它本身是强联通最小的点,那么在找到此点时会把它上面的点全部 pop 出去,另一种是它不是最小点,那么在遍历的过程中总会到第一种情况把它排除。
Tarjan 程序是正确无误的,然后最后要跑一个拓扑,然鹅我不大会。luogu 上爆了 40pt,然后去看别人的题解秒懂。用拓扑可以优化掉 ans、Q、new_val 等等数组,估计就 80pt 了,然后我们还得用 dp 去解决菊花图这种类型的数据。
这道题还给人一个教训是,对于缩点的题,我们记录下每条路径的开始与结束去构造新图,没必要单独列个 Q 这种数组。
40pt 代码如下:
(其实会个 Tarjan 就行了吧)









