并查集与带权并查集(转)

并查集

并查集是一个很高效算法,理解起来也很简单,写起来更简单。

①fat[i] = i;

②找到一个点的祖先

int findfat(int x)  
{  
    if(fat[x] == x) return x;  
    return findfat(fat[x]);  
}  

③二中的方法肯定不好,因为如果数据比较极端,那么并查集就退化成一个链了
如果加入了路径压缩,并查集这个算法就更高效了。

int findfat(int x)//递归写法  
{  
    if(fat[x] == x) return x;  
    fat[x]=findfat(fat[x]);  
    return findfat(fat[x]);  
}  
int findfat(int x)//非递归写法 更好,因为不会RE  
{  
    int root=x;  
    while(root != fat[root])//先要找到根节点r   
    {  
        root=fat[root];  
    }  
    int y=x;  
    while(y!=root)  
    {  
        int fath=fat[y];  
        fat[y]=root;  
        y=fath;  
    }  
    return r;  
}  

④合并

void join(int x,int y)  
{  
    int fatx=findfat(x),faty=findfat(y);  
    if(fatx != faty)  
    {  
        fat[fatx]=faty;  
    }  
}  

带权并查集

带权值的并查集只不过是在并查集中加入了一个value[ ]数组
value[ ]可以记录很多种东西,不一定是类似距离这种东西,也可以是相对于根节点的状态
加入了权值,函数应该有一些改变
①找到一个点的祖先

int findfat(int x)  
{  
    if(fat[x] == x) return x;  
    int tmp=fat[x];  
    fat[x]=findfat(fat[x]);  
    //在此处修改val比如:  
    value[x]=value[tmp]+1;  
    return fat[x];   
}  

猜你喜欢

转载自blog.csdn.net/linghugoolge/article/details/81671403