并查集简单总结

普通并查集

一般地运用并查集可以简单的判断连通性,以及可以用来解决最短路问题。普通的并查集有路径压缩和按秩合并两种优化的方法。路径压缩的并查集写法如下

int Getp(int a){
    if(a!=f[a]) f[a]=Getp(f[a]);
    return f[a];
}

void join(int a,int b){
    int fa = Getp(a);
    int fb = Getp(b);
    if(fa!=fb) f[fa]=fb;
}

带权并查集

带权并查集可以理解为就是向量之间的关系。

如果要合并A和B则要注意的是两个向量的加。
写法以食物链为例

int Getp(int x)//找寻父节点+路径压缩
{
    if(x==f[x]) return f[x];
    int y=Getp(f[x]);
    deep[x]=(deep[x]+deep[f[x]])%3;
    return f[x]=y;
}
int join(int typ,int x,int y)
{
    int fx=Getp(x);
    int fy=Getp(y);
    if(fx==fy)//共父节点才能判断出关系
    {
        if((deep[x]-deep[y]+3)%3==typ-1)
            return 0;
        return 1;
    }
    f[fx]=fy;
    deep[fx]=(-deep[x]+typ-1+deep[y]+3)%3;
    return 0;
}

带撤销并查集

下面就谈到按秩合并的写法了。某些情况下时必须要运用按秩合并的方法的,虽然路径压缩卸起来更为方便。 按秩合并主要是能解决一类带撤销的问题。

void Back(int tag) { //撤销到tag的位置
    for (; cnt!= tag; Cnt --) { //cnt代表当前
        if (que[cnt] < 0) deep[-que[cnt]] --; 
        else {
            fa[que[cnt]] = que[cnt];
            val[que[cnt]] = 0;
        }
    }
}

void Push(int u, int v, int val) {  //合并u,v
    if (deep[u] > deep[v]) swap(u, v);
    if (deep[u] == deep[v]) {
        deep[v] ++;
        que[++ cnt] = -v;
    }
    fa[u] = v, val[u] = val;
    que[++ cnt] = u;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值