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



    删除节点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 ;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值