算法分析與設計 並查集

並查集學習筆記

並查集(union-find set)是一抽象數據類型。它所處理的是“集合”之間的關係,即動態地維護和處理集合元素之間複雜的關係,
當給出兩個元素的一個無序對(a,b)時,需要快速“合併”a和b分別所在的集合,這其間需要反覆“查找”某元素所在的集合。“並”、“查”和“集”三字由此而來。

合併元素所在集合、查找元素所在集合

數組實現

並查集支持的操作

MAKE(x):建立一個新的集合,其僅有的成員(同時就是代表)是x。由於各集合是分離的,要求x沒有在其它集合中出現過。
UNIONN(x,y):將包含x和y的動態集合(例如Sx和Sy)合併爲一個新的集合,假定在此操作前這兩個集合是分離的。結果的集合代表是Sx∪Sy的某個成員。一般來說,在不同的實現中通常都以Sx或者Sy的代表作爲新集合的代表。此後,由新的集合S代替了原來的Sx和Sy。
FIND(x):返回一個指向包含x的集合的代表。

查找

int find(int x) {  //用非遞歸的實現  
  while (father[x] != x) x = father[x];  
  return x;
  
}
int find(int x){//用遞歸的實現  
    if (father[x] != x){  
        return find(father[x]);  
    } else{  
        return x;  
    }   
}

合併

void unionn(int r1,int r2){
      father[r2] = r1;
  }
    int main(){
      cin >> n >> m;
      for (i = 1; i <= n; i++)
          father[i] = i;           //建立新的集合,其僅有的成員是i
      for (i = 1; i <= m; i++) {
          scanf("%d%d",&x,&y);
          int r1 = find(x);
          int r2 = find(y);
          if (r1 != r2){
                unionn(r1,r2);
            }   
      }    
      cin >> q;
      for (i = 1; i <= q; i++)  {
          scanf("%d%d",&x,&y);
          if (find(x) == find(y)){
                printf("Yes\n");
            } else {
                printf("No\n");
            }
      }
      return 0;
  }
本文由博客一文多發平臺 OpenWrite 發佈!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章