并查集解决的不是“找元素”,而是“判断两个东西是不是已经连在一起”。你可以把它理解成一堆集合在不断合并:今天把 a 和 b 连起来,明天把 b 和 c 连起来,后天再问 a 和 c 是不是同一组。如果每次都真的把整组数据搬来搬去,代价会很大,所以并查集故意只存一件事:每个点先指向一个“父节点”,最后一路走到代表整个集合的根。
容易踩坑的地方也很直接。第一,union(a, b) 不是把 a 挂到 b,而是把 find(a) 的根和 find(b) 的根合并;如果你直接拿原节点乱连,整棵树就坏了。第二,路径压缩优化的是 find,不是 union 本身,所以很多代码看起来像“查找函数偷偷改了数据”,这不是副作用失控,这是设计本意。第三,如果题目需要维护集合大小、边数、权值差,你不能只会裸模板,因为额外信息要么挂在根上,要么在路径压缩时一起更新,不然答案会错得很隐蔽。