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