並查集

並查集

 

求助編輯百科名片

並查集   
並查集

在一些有N個元素的集合應用問題中,我們通常是在開始時讓每個元素構成一個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查找一個元素在哪個集合中。這一類問題近幾年來反覆出現在信息學的國際國內賽題中,其特點是看似並不複雜,但數據量極大,若用正常的數據結構來描述的話,往往在空間上過大,計算機無法承受;即使在空間上勉強通過,運行的時間複雜度也極高,根本就不可能在比賽規定的運行時間(1~3秒)內計算出試題需要的結果,只能採用一種全新的抽象的特殊數據結構——並查集來描述。

 

目錄

定義
主要操作
  1. 初始化
  2. 查找
  3. 合併
例題
  1. 問題實質
  2. 單鏈表實現
  3. 並查集森林
  4. 注意事項
代碼
  1. c++
  2. pascal
展開

 

 

編輯本段定義

  並查集是一種樹型的數據結構,用於處理一些不相交集合(Disjoint Sets)的合併及查詢問題。常常在使用中以森林來表示。
 
  集就是讓每個元素構成一個單元素的集合,並就是按一定順序將屬於同一組的元素所在的集合合併。
 

編輯本段主要操作

初始化

  把每個點所在集合初始化爲其自身。
 
  通常來說,這個步驟在每次使用該數據結構時只需要執行一次,無論何種實現方式,時間複雜度均爲O(N)。

查找

  查找元素所在的集合,即根節點。

合併

  將兩個元素所在的集合合併爲一個集合。
 
  通常來說,合併之前,應先判斷兩個元素是否屬於同一集合,這可用上面的“查找”操作實現。

#include <stdio.h>

int set[101000];
int num[101000];
int maxn = 1;

void make_set(  )
{
  for( int i = 1; i <= 100000; i++)
  {
     set[i] = i;
     num[i] = 1;
  }
}

int find( int x)
{
  /*
  if( x != set[x] )
      set[x] = find(set[x]);
  return set[x];
  */
  return x == set[x] ? set[x] : set[x] = find(set[x]);
 
}

void merge( int x, int y)
{
   int x1 = find(x);
   int y1 = find(y);
   if( x1 != y1)
   {
      set[x1] = y1;
      num[y1] += num[x1];
   maxn = maxn > num[y1] ? maxn : num[y1];   
   }
}

int main( )
{
 int N, a, b;
 while( scanf("%d",&N)!= EOF )
 {
   maxn = 1;
   make_set( );
   for( int i = 1; i <= N; i++)
   {
   scanf("%d%d",&a,&b);
   merge(a,b);
   }
   printf("%d\n",maxn);   
 } 
 return 0;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章