并查集 ,删除节点(图画展示)

来源:互联网 发布:编程解决鸡兔同笼问题 编辑:程序博客网 时间:2024/05/02 02:47



    删除节点x, 找个新的节点y替换x , father[y] = x ;

   


图一:   删除节点4 , 4 替换成5 , 5的父亲为5 。 




图二:   1,2,3的父亲还是为4




  

图三: 相当于做了一个映射。  

1->1   , 2->2  ,  3->3 , 4->5  。

                                           

 father[1] = 4 ,  father[2] = 4 ,  father[3] = 4  ,  father[5] = 5 ,     

 没有father【4】 , 因为4已经被5给替换掉了。   




图四: 合并 1 , 4 

           father【1 ->1】 = 4 ;

           father【4 ->5】 = 5 ;

       为了看清楚,特让father[5] = 4 ; 

测试地址http://acm.hdu.edu.cn/showproblem.php?pid=2473 

const int Max_N = 2000008 ;struct Node{       int  father ;       int  Replace ;};Node  node[Max_N] ;int   N ;void  build(){      int i ;      for(i = 0 ; i < N ; i++){           node[i].father = i ;           node[i].Replace = i ;      }}int  find_father(int x){     if(node[x].father == x)        return x ;     else        return node[x].father = find_father(node[x].father) ;}void MerGe(int x , int y){     int f_x = find_father(x) ;     int f_y = find_father(y) ;     if(f_x != f_y)        node[f_x].father = f_y ;}void Delete(int x){     node[x].Replace = N ;     node[N].father = N ;     N++ ;}int  main(){     int M , n , i  , x , y , cas = 1 ;     char str[2] ;     while(scanf("%d%d",&N ,&M)){          if(N == 0 && M == 0)              break ;          n = N ;              build() ;          while(M--){               scanf("%s" ,str) ;               if(str[0] == 'M'){                   scanf("%d%d" ,&x ,&y) ;                   MerGe(node[x].Replace , node[y].Replace) ;               }               else{                   scanf("%d" ,&x) ;                   Delete(x) ;               }          }          set<int>ans ;          ans.clear() ;          for(i = 0 ; i < n ; i++)               ans.insert(find_father(node[i].Replace)) ;          printf("Case #%d: %d\n" , cas++ , ans.size()) ;     }     return 0 ;}


0 0