并查集
处理不相交集合的合并问题。
初始化:
int f[maxn]; //父亲数组,记录节点的父节点位置 void init(int n){ //将每个节点的父节点初始化为它本身 for(int i=0;i<n;i++){ f[i]=i; } }
查询根节点:
int find(int x){ //每次查询都要向上查询到根节点 ,坏情况下复杂度高 return f[x]==x?x:find(f[x]); }
路径压缩优化:(一旦查询到一次根节点,就将根节点作为父节点
int find(int x){ return f[x]==x?x:f[x]=find(f[x]); }
判断是否属于同一个集合:
bool same(int x,int y){ return find(x)==find(y); }
合并:
void uni(int x,int y){ int fx=find(x); int fy=find(y); if(fx!=xy) f[fy]=fx; }
按秩合并:
void uni(int x,int y){ int fx=find(x); int fy=find(y); if(fx==fy) return; if(rank[fx]<rank[fy]) f[fx]=fy; else{ f[fy]=fx; if(rank[fx]==rank[fy]) rank[fx]++; } }//rank小的向rank大的连边,使树的高度尽量小