tarjan求lca

好玩爱玩。
我们将 \(lca(u,v)\) 复制一遍,然后有 \(lca(v,u)\)。然后把 \(lca(x,y)\) 这个询问挂到 \(x\) 上,其值为 \(y\)。然后进行 \(dfs\),每个点的并查集存的是当前子树集合已经遍历过的最小的点。所以如果这个点有询问,如果y已经被访问过了,那么就询问 \(y\) 所在集合的深度最小的点,利用 \(dfn\) 容易理解,并查集将儿子并到父亲上可以保证集合的根是 \(lca\)。有点妙的。
时间复杂度如何证明。主要是路径压缩这里比较搞,容易发现,想要把这个卡到最大,就把这个询问全挂到根上。路径压缩一共会执行 \(n-1\) 次。因为每条树上的边会贡献一次。那普通的并查集并是不这样的,是 \(O(\alpha n)\) 的,为什么呢。

posted @ 2025-07-09 10:25  wuhupai  阅读(7)  评论(0)    收藏  举报