带关系的并查集,每次都存自己和父节点的关系即可。0表示相同,1表示不同
#include <iostream>
#include <stdio.h>
using namespace std;
#define MMAX 100050
int p[MMAX];
int rank[MMAX];
void init() {
for(int i = 0; i < MMAX; i++) {
p[i] = i;
rank[i] = 0;
}
}
int find(int x) {
if(p[x] == x) return x;
else {
int k = p[x];
p[x] = find(p[x]);
rank[x] = (rank[x]+rank[k])%2;
}
return p[x];
}
int unionSet(int a, int b) {
int t1 = find(a);
int t2 = find(b);
if(t1 == t2) {
if(rank[a] == rank[b]) return 1;
return 0;
}
p[t2] = t1;
rank[t2] = (rank[a] - rank[b] + 1)%2;
return 0;
}
int main() {
int t;
int n, m;
scanf("%d", &t);
while(t--) {
init();
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++) {
int a, b;
char cmd[3];
scanf("%s%d%d", cmd, &a, &b);
if('D' == cmd[0]) {
unionSet(a, b);
}
else {
int t1 = find(a);
int t2 = find(b);
if(t1 != t2) printf("Not sure yet.\n");
else if(t1 == t2 && rank[a] == rank[b]) printf("In the same gang.\n");
else printf("In different gangs.\n");
}
}
}
return 0;
}