并查集

方法1:

用编号最小的元素标记所在集合;

定义一个数组 set[1..n] ,其中set[i] 表示元素i 所在的集合;

O(1):

find1(x)
{
    return set[x];
}

O(n)

Merge1(a,b)
{   i = min(a,b);
     j = max(a,b);
     for (k=1; k<=N; k++) {
         if (set[k] == j)
            set[k] = i;
     }
}

方法2;

每个集合用一棵“有根树”表示定义数组 set[1..n]

set[i] = i , 则i表示本集合,并是集合对应树的根
set[i] = j, j != i, 则 j 是 i 的父节点. 
find2(x)
{
   r = x;
   while (set[r] != r)
      r = set[r];
   return r;
} //O(n)

merge2(a, b)
{
    if (a<b)
       set[b] = a;
    else
       set[a] = b;
}//O(1)

 

带路径压缩的查找算法

第一步,找到根结点
第二步,修改查找路径上的所有节点,将它们都指向根结点

find3(x)
{
      r = x;
      while (set[r] <> r) //循环结束,则找到根节点
          r = set[r];       
      i = x;
      while (i <> r) //本循环修改查找路径中所有节点
      {   
          j = set[i];
         set[i] = r;
          i = j;
      }

}

//并查集练习

HDOJ-1558 Segment set
HDOJ-1811 Rank of Tetris
HDOJ-1829 A Bug's Life
HDOJ-1198 Farm Irrigation

ZOJ 2740

posted @ 2009-12-03 11:30  zedzhao  阅读(149)  评论(0编辑  收藏  举报