算法导论21(用于不相交集合的数据结构)

来源:互联网 发布:ios软件下载 编辑:程序博客网 时间:2024/05/16 07:31

不相交集合数据结构(disjoint-set data structure)即并查集(union-find set)

int p[n],r[n];void MakeSet(int x){    p[x]=x;    r[x]=0;}//递归int FindSet(int x){    if(x!=p[x])p[x]=FindSet(p[x]);    return p[x];}int FindSet(int x){    return x==p[x]?x:Findset(p[x]);}//非递归int FindSet(int x){    int r=x;    while(r!=p[r])r=p[r];    int y;    while(x!=p[x])    {        y=p[x];        p[x]=r;        x=y;    }}void Link(int x,int y){    if(r[x]>r[y])p[y]=x;    else     {        p[x]=y;        if(r[x]==r[y])++r[y];    }}void Union(int x,int y){    Link(FindSet(x),FindSet(y));}


POJ1611

http://poj.org/problem?id=1611

#include<iostream>using namespace std;const int N=30001;int p[N],r[N];    void MakeSet(int x)  {      p[x]=x;      r[x]=0;  }   int FindSet(int x)  {      if(x!=p[x])p[x]=FindSet(p[x]);      return p[x];  }  void Link(int x,int y)  {      if(r[x]>r[y])p[y]=x;      else       {          p[x]=y;          if(r[x]==r[y])++r[y];      }  }    void Union(int x,int y)  {      Link(FindSet(x),FindSet(y));  } int main(){int n,m,k,firstStu,stu,sum;while(cin>>n>>m&&(m||n)){for(int i=0;i<n;++i)MakeSet(i);for(int i=0;i<m;++i){cin>>k;if(k>=1)cin>>firstStu;{for(int j=1;j<k;++j){cin>>stu;Union(firstStu,stu);}}}sum=1;for(int i=1;i<n;++i){if(FindSet(i)==FindSet(0))++sum;}cout<<sum<<endl;}return 0;}


POJ2524

http://poj.org/problem?id=2524

#include<iostream>using namespace std;const int N=50001;int p[N],r[N];    void MakeSet(int x)  {      p[x]=x;      r[x]=0;  }   int FindSet(int x)  {      if(x!=p[x])p[x]=FindSet(p[x]);      return p[x];  }  void Link(int x,int y)  {      if(r[x]>r[y])p[y]=x;      else       {          p[x]=y;          if(r[x]==r[y])++r[y];      }  }    void Union(int x,int y)  {      Link(FindSet(x),FindSet(y));  } int main(){    int n,m,first,second,sum,num=1;    while(cin>>n>>m&&(m||n))    {        for(int i=1;i<=n;++i)MakeSet(i);        for(int i=0;i<m;++i)        {            cin>>first>>second;            Union(first,second);        }        sum=0;        for(int i=1;i<=n;++i)        {            if(i==FindSet(i))++sum;        }        cout<<"Case "<<num++<<": "<<sum<<endl;    }    return 0;}




0 0