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

来源:互联网 发布:sql server 2008dev 编辑:程序博客网 时间:2024/05/30 05:08

一直没想过自己写的并查集的复杂度= =。。。看那一行代码还挺窃喜——贴一下正版的启发式合并,这样复杂度就真正到了反阿克曼函数那什么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 ]++;    }    }


0 0