并查集——启发式合并,路径压缩

一直没想过自己写的并查集的复杂度= =。。。看那一行代码还挺窃喜——贴一下正版的启发式合并,这样复杂度就真正到了反阿克曼函数那什么balabala


一个优化是:把小的树合并到大树中,这样会让深度不太大。这个优化称为启发式合并。

一个优化是把沿途上所有结点的父亲改成根。这一步是顺便的,不增加时间复杂度,却使得今后的操作比较快。这个优化称为路径压缩
用 p[i] 表示 i 的父亲,而 rank[i] 表示 i 的秩,并用秩来代替深度做刚才提到的启发式合并。
void makeset ( int x ){
    rank [ x ] = 0;
    p[x] = x;
}
int findset ( int x )
{
    int px = x , i ;
    while ( px != p [ px ]) px = p [ px ]; // find root
    while ( x != px ) // path compression
    {
        i = p [ x ];
        p [ x ] = px ;
        x = i;
    }
    return px ;
}
void unionset ( int x , int y )
{
    x = findset ( x );
    y = findset ( y );
    if ( rank [ x ] > rank [ y ]) p [ y ] = x ;
    else{
        p[x ] = y;
        if ( rank [ x ] == rank [ y ]) rank [ y ]++;
    }    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值