并查集优化

来源:互联网 发布:房间刮塑面积算法 编辑:程序博客网 时间:2024/06/16 01:22

按秩合并

矮树合并到高树

void Union(int a, int b) {          if(tree[a].weight == tree[b].weight) {       tree[b].parent = a;           tree[a].weight += 1;          }        else if (tree[a].weight > tree[b].weight) {         tree[b].parent = a;        }        else {        tree[a].parent = b;        }}

路径压缩


将查找到的节点均指向根节点

递归

int Find(int x) {         if(root[x] == -1)        {        return x;    }      return root[x] = Find(root[x]);}

非递归

int Find (int n) {        int r = n;           while (r != root[r])      {               r = root[r];         }            int x = n, y;            while (x != r) {  //压缩路径,全部赋值为根结点的值                 y = root[x];               root[x] = r;              x = y;           }        return r;}


例题 HDU 1856   http://acm.hdu.edu.cn/showproblem.php?pid=1856

#include <stdio.h>#define maxn 10000005struct Node{    int m;    int rank;}tree[maxn];int mm,pre[maxn];int Find(int x){    int p = x;    while(tree[p].m != p)    {        p = tree[p].m;    }    int i = x;    while(i != p)    {        int j = tree[i].m;        tree[i].m = p;        i = j;    }    return p;}int hb(int x,int y){    int fx=Find(x);    int fy=Find(y);    if(fx!=fy)        {        tree[fy].rank+= tree[fx].rank;        if(tree[fy].rank>mm)            mm=tree[fy].rank;        tree[fx].m=fy;    }}int main(){    int t,i;    int x,y;    while(~scanf("%d",&t))    {       mm=1;       for(i=0;i<t;i++)       {           tree[i].m=i;           tree[i].rank=1;       }       for(i=0;i<t;i++)       {           scanf("%d%d",&x,&y);           hb(x,y);       }       printf("%d\n",mm);    }}



0 0