并查集的删除操作 点击打开链接
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 ;
}