数据结构之并查集(hdu1988 hdu2492)

    xiaoxiao2021-04-15  34

    (抄知识点方便自己复习)//摘自俞勇的acm国际大学生程序设计竞赛,知识与入门

    基本概念

    不相交集为一组彼此不相交(没有公共元素)的集合。并查集算法作用于一个不相交集,实际应用中可以在近乎常数的时间内完成下列两种操作。

    1:查找(find):确定元素所在的集合。一般用来判断两个元素是否在同一个集合。

    2:合并(Union):将两个集合合并成一个集合。

    对于查找操作,假设需要确定x所在的集合,也就是确定集合的代表元。可以沿着parent【x】不断在树形结构中向上移动,直到到达根节点,根节点即代表元。

    判断两个元素是否属于同一个集合,只需看他们的代表元是否相同即可。为了加快速度,每次查找操作的过程中,可以将x到根节点路径上的所有点的parent设为根节点,

    这样下次再次查找时就不必再沿着路径一步步寻找了,该优化方法为压缩路径。

    //hdu1988 带权并查集

    #include <iostream> using namespace std; const int maxn=30005; int fa[maxn],d[maxn],s[maxn]; int find(int x){     if(fa[x]==x)         return x;//若是根节点就直接返回     int t=fa[x];//否则记录点x的当前根节点。     fa[x]=find(fa[x]);//更新元。     d[x]+=d[t];//将其父节点的深度跟新跟x;     return fa[x]; } void Move(int x,int y){     x=find(x),y=find(y);//找到对应的元     fa[x]=y;//跟新x的根节点     d[x]+=s[y];//更新其x的深度,y的树的大小,x树的大小。     s[y]+=s[x];     s[x]=0; } int main() {     for(int i=0;i<maxn;i++){         fa[i]=i;         s[i]=1;         d[i]=0;     }     int p;     cin>>p;     while(p--){         char str[1];int a[2];         cin>>str[0];         if(str[0]=='M'){             cin>>a[0]>>a[1];             Move(a[0],a[1]);         }         if(str[0]=='C'){             cin>>a[0];             find(a[0]);             cout<<d[a[0]]<<endl;         }     }     //cout << "Hello world!" << endl;     return 0; }

    hdu 2492

    http://blog.csdn.net/lxmky/article/details/7654916#//摘自

    #include <iostream> #include <cstring> using namespace std; const int maxn=5005; int f[maxn],relations[maxn]; int find(int x){     int temp=f[x];     if(f[x]==x)     return x;     x=find(temp);     relations[x]=(relations[x]+relations[f[temp]])%2;     return f[x]; } void unionset(int a,int b){     int x=find(a);int y=find(b);     if(x==y)     return ;     f[x]=y;     relations[x]=(relations[a]-relations[b]+1)%2;     return ; } int main() {     int t,count=1;     cin>>t;     while(t--){         int n,m;         cin>>n>>m;         memset(relations,0,sizeof(relations));         for(int i=1;i<=n;i++){             f[i]=1;         }         int flag = 1;         for(int i = 0; i < m; i++)         {             int tmp1,tmp2;             cin>>tmp1>>tmp2;             if(find(tmp1) == find(tmp2))             {                 if(relations[tmp1] != (relations[tmp2] + 1) % 2)  //如果不满足异性关系,有矛盾                     flag = 0;             }             else             {                 unionset(tmp1, tmp2);             }         }         if(flag)         {             cout<<"Scenario #"<<count<<":"<<endl<<"No suspicious bugs found!"<<endl<<endl;         }         else         {             cout<<"Scenario #"<<count<<":"<<endl<<"Suspicious bugs found!"<<endl<<endl;         }     }     //cout << "Hello world!" << endl;     return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-671703.html

    最新回复(0)