并查集分两种:带边权和扩展域
-
带边权:带边权的并查集维护的是相对关系,也就是相对于根的关系, 能用并查集来做个核心思想有两点,第一点就是关系具有传递性, 也就是说,如果已知x,y关系也知道y,z 的关系,那么必然知道x,z的关系第二点是要必须具有对称性,无向边a能到b同时b也能到a
-
扩展域:维护的是多组关系。怎么理解呢?这里有一种理解的方式就是:假如存在x种性质,一共有n个节点,那么对于每个物品y来说f[y]代表y是第一种性质, f[y + n]代表y是第二种性质 … f[y + (x -1)n]代表y是第x种性质。
- 扩展域的并查集处理很方便,和普通并查集找根节点一样
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
- 如果处理关系和矛盾?以关押罪犯这道题为例,首先定义f[x] 是犯人x所在的监狱, f[x + n]是另一座监狱,如果这个时候我们要维护a, b不在一个监狱。就先判断如果p[f[a]] == p[f[b]] 那么就矛盾,反正就把p[f[a]] = p[f[n + b]], p[f[b]] = p[f[n + a]] 意思就是把a所在的监狱与b不在的监狱合并,同时把b所在的监狱与a不在的监狱合并。
- 我觉得这种理解方式不错