zoj 3789 并查集 删除操作

并查集的删除操作  点击打开链接


L a b时,将a和b加入一个集合,且 a ,  b 不同 (a ,b 不同,a , c 不同 那么b c 相同)。

Q a b时,若a和b的权值差为奇数,则方向相反,否则方向相同。 不在一个几个就无法查询。

D a时, 由于被删除的节点的信息以后还会用到,所以就新建一个点作为该点拿出去。

S a时, 直接查询a的祖先节点上储存的集合元素个数。


const  int  maxn  =  600008 ;
int   father[maxn] ;
int   replase[maxn] ;
int   high[maxn] ;
int   sum[maxn] ;
int   n , m ;

void  init(){
      int i ;
      for(i = 1 ;  i <= n + m ; i++){
           father[i] = i ;
           replase[i] = i ;
           sum[i] = 1 ;
           high[i] = 0 ;
      }
}

int   getfather(int x){
      if(x == father[x])  return x ;
      int t = getfather(father[x]) ;
      high[x] += high[father[x]]  ;
      return  father[x] = t ;
}

void  merg(int x , int y){
      int fx = getfather(x) ;
      int fy = getfather(y) ;
      if(fx != fy){
            father[fx] = fy  ;
            sum[fy] += sum[fx] ;
            high[x] = high[y] + 1 ;
      }
}

int  main(){
     int i  , u , v  , fu  , fv  ;
     char s[2]  ;
     while(cin>>n>>m){
           init() ;
           while(m--){
                scanf("%s" , s) ;
                if(s[0] == 'L'){
                    scanf("%d%d" ,&u , &v) ;
                    merg(replase[u] , replase[v]) ;
                }
                else if(s[0] == 'D'){
                    scanf("%d" ,&u) ;
                    sum[getfather(replase[u])]-- ;
                    replase[u] = ++n ;
                }
                else if(s[0] == 'S'){
                    scanf("%d" ,&u)  ;
                    printf("%d\n" , sum[getfather(replase[u])]) ;
                }
                else{
                    scanf("%d%d" ,&u ,&v) ;
                    fu = getfather(replase[u]) ;
                    fv = getfather(replase[v]) ;
                    if(fu != fv) puts("Unknown") ;
                    else if((high[replase[u]] - high[replase[v]]) & 1)
                          puts("Different") ;
                    else  puts("Same") ;
                }
           }
     }
     return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值