OI模板 并查集
并查集(路径压缩):
const int N=1;
struct DisjointSet{
int n,fa[N];
inline void init(){//初始化
for(int i=0; i<N; ++i) fa[i]=i;
return;
}
inline int gf(int x){//查询 x 所在集合代表元
return x==fa[x] ? x : fa[x]=gf(fa[x]);
}
inline void merge(int x,int y){//合并 a,b 所在集合
fa[gf(x)]=gf(y);
return;
}
inline bool find(int x,int y){//查询 a,b 是否在同一集合
return gf(x)==gf(y);
}
};
例题:Luogu P1551 亲戚。
边带权并查集:
const int N=1;
struct DisjointSet{
int n,fa[N];
int d[N];//节点到 fa[节点] 距离
int size[N];
inline void init(){//初始化
for(int i=0; i<N; ++i) fa[i]=i,d[i]=0,size[i]=1;
return;
}
inline int gf(int x){//查询 x 所在集合代表元
if(x==fa[x]) return x;
int root=gf(fa[x]);
d[x]+=d[fa[x]],fa[x]=root;//因具体问题可能会稍加改动
return root;
}
inline void merge(int x,int y){//合并 a,b 所在集合
int a=gf(x),b=gf(y);
fa[a]=b;
d[a]=size[b],size[b]+=size[a];//因具体问题可能会稍加改动
//d[a]=-d[x]+d[y]+val; 有的题是这么写的
return;
}
inline bool find(int x,int y){//查询 a,b 是否在同一集合
return gf(x)==gf(y);
}
} ;
例题:Luogu P1196 [NOI2002] 银河英雄传说。
扩展域并查集
板子和普通并查集一样,注意空间。