并查集基础

来源:互联网 发布:convertio for mac 编辑:程序博客网 时间:2024/06/05 04:57

并查集中我们用一个一维数组father[N]来表示每一个节点的父亲节点。

并查集的初始化操作

for(int i=1;i<=n;i++)father[i]=i;//每个节点的父亲节点定义为自己

并查集的查找函数

int find(int x)       //查找x元素所在的集合,回溯时压缩路径{    if (x!=father[x])    {        father[x] = find(father[x]);     //回溯时的压缩路径    }         //从x结点搜索到祖先结点所经过的结点都指向该祖先结点    return father[x];}


上面是一采用递归的方式压缩路径, 但是,递归压缩路径可能会造成溢出栈,我曾经因为这个RE了n次,下面我们说一下非递归方式进行的路径压缩:

int find(int x){    int k, j, r;    r = x;    while(r!=father[r])     //查找跟节点        r=father[r];      //找到跟节点,用r记录下    k = x;    while(k!=r)             //非递归路径压缩操作    {        j=father[k];         //用j暂存parent[k]的父节点        father[k]=r;        //parent[x]指向跟节点        k=j;                    //k移到父节点    }    return r;         //返回根节点的值}


并查集的合并函数

void join(int x,int y){    int xx=find(x);    int yy=find(y);    if(xx!=yy)    father[xx]==yy;   //将x定点的父亲节点设为y定点的父亲节点的自定点,从而将两定点并到同一集合。}


附上一道基础的并查集的题目

poj 2236

附上代码

#include<iostream>#include<cmath>#include<string.h>using namespace std;int n,d;double x[1005],y[1005];bool check[1005];int father[1005];int find(int x){    if(x!=father[x])    {        father[x]=find(father[x]);    }    return father[x];}void join(int x,int y){    int xx=find(x);    int yy=find(y);    if(xx!=yy)    father[xx]=yy;}int main(){    cin>>n>>d;    for(int i=1;i<=n;i++)        cin>>x[i]>>y[i];    for(int i=1;i<=n;i++)        father[i]=i;        memset(check,false,sizeof(check));        char a;        int p,q;    while(cin>>a)    {        if(a=='O')        {            cin>>p;            check[p]=true;            for(int i=1;i<=n;i++)            {                if(i==p)                    continue;                if(check[i])                {                    double dis=sqrt((x[p]-x[i])*(x[p]-x[i])+(y[p]-y[i])*(y[p]-y[i]));                     if(dis<=d)                     {                         join(i,p);                     }                }            }        }        else if(a=='S')        {            cin>>p>>q;            if(find(p)==find(q))                cout<<"SUCCESS"<<endl;            else                cout<<"FAIL"<<endl;        }    }    return 0;}



原创粉丝点击