题目链接:https://www.luogu.org/problemnew/show/P1196
加权并查集的板子题。
加权并查集:
普通的并查集我们都知道是把一些点合并成一个图,既然是图,那么就可以带上边权,这就是所谓的加权并查集了。
在具体的实现可以看这个题目,我们维护两个数组dis[i]表示i和f[i]之间的距离,num[i]表示i所在集合的元素个数。
加权并查集的操作和基本的并查集并无两样:
int find(int x) {
if (x!=f[x]) {
int tmp=f[x];
f[x]=find(f[x]);
dis[x]+=dis[tmp];
num[x]=num[f[x]];
}
return f[x];
}
void merge(int a, int b) {
int t1=find(a), t2=find(b);
if (t1!=t2) {
f[t1]=t2;
dis[t1]=num[t2];
num[t2]+=num[t1];
num[t1]=num[t2];
}
return ;
}
int query(int a, int b) {
if (find(a)!=find(b)) return -1;
else return abs(dis[a]-dis[b])-1;
}
上面是这个题目的并查集各个操作的代码。因为是近乎板子的题目,所以有一定的普适性。
ps:加权并查集,要具体的题目具体灵活维护,思路当然跟这道题大体一致。