并查集学习总结

并查集作用:判断两个元素是否在一个集合内。

方式:通过记录每个元素对应的par[x]值来判断,如果两者相等,则为同组,否则为不同组。

_rank[maxn]的作用:_rank[i]记录的是每一个节点所在的树的高度,查询的时候意义不大,但是当两棵树合并的时候,当树的高度小的树连接到树的高度高的树会让树的整体高度较小,而保证查询优化。

状态压缩:并查集的状态压缩通过如下代码实现:

int find(int x){
    if(par[x]==x)
        return x;
   }else{
        return par[x]=find(par[x]);
    }
}

上面的代码可以让所有的节点都直接连到根节点上,这样无论原本的树高度为多少,在这样一次操作后,树的高度都为2。所以在有状态压缩的情况下,_rank的作用非常小,几乎可以忽略。

模板:

const int maxn=1e5+5;
int par[maxn];

void init(int n){
    for(int i=0;i<n;i++){
        par[x]=i;
    }
}

int find(int x){
    if(par[x]==x){
        return x;
    }else{
        return par[x]=find(par[x]);
    }
}

bool unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)return false;
    else{
        par[x]=y;//此处par[y]=x;也可以 
        return true;
    }
}

bool same(int x,int y){
    return find(x)==find(y);
} 

其中unite函数也可以不返回布尔值,之所以在那里写了布尔值,是因为这样可以判断是否成功连接,在MST(最小生成树)的生成过程中使用较为方便。

例题:

1.连通

2.食物链

3.真假话

4.反向连通

5.MST

回来找时间再把例题的具体内容补上...

(未完待续)

posted @ 2018-04-26 09:58  87hbteo  阅读(123)  评论(0编辑  收藏  举报