并查集是一种非常重要的数据结构。之前听的晕乎乎的,今天自己学了一下,发现很简单
为什么要用并查集?
因为快!
可以迅速找到祖宗,非常好用!
一开始,很简单,所有人都是自己的祖宗。因此
for (int i=1;i<100000;i++)
ren[i]=i;
接着,每次输入时,有一个寻找祖宗的办法。
int find(int x)
{
if (x!=ren[x])
return ren[x]=find(ren[x]);
else
return x;
}
自己等于自己,说明这就是老祖宗,否则继续往上走。这里最巧妙的是,走的时候也把每个孙子、重孙、玄孙直接变成儿子,可以一步到位查到祖宗。
当然,还要合并一些值
void unite(int x,int y)
{
x=find(x);
y=find(y);
if (x==y)return;
ren[x]=y;
}
找到两人的祖宗,如果是同一个,就什么也不做,否则让x的祖宗变成y的祖宗。
查询当然只要find两个值的祖宗就行了
总结:
并查集,实际上就是一堆值,和祖宗之间的映射关系。哪些是一类,就会有一个相同的祖宗。找到这个们就是一类。