第一次做这种类型的并查集。re数组代表所在的类,因为只能从当前情况来判断两个人是
不是在一个犯罪集团。所以D操作时保证两个人的re不同。两个有相同的根结点,代表情况
已知,否则为情况未知。
/*Accepted 948K 360MS C++ 1190B 2012-07-27 17:16:34*/ #include<cstdio> #include<cstring> #include<cstdlib> const int MAXN = 100111; int p[MAXN], re[MAXN]; int n, m; char ans[3][20] = {"In different gangs.", "In the same gang.", "Not sure yet."}; void init() { for( int i = 0; i <= n; i ++) { p[i] = i, re[i] = 0; } } int find_set( int x) { if(p[x] == x) return x; int parent = find_set(p[x]); re[x] = (re[x] + re[p[x]]) & 1; //子孙与根结点的re不同 return p[x] = parent; } void union_set( int x, int y) { int nx = find_set(x), ny = find_set(y); p[nx] = ny; re[nx] = (re[x] + re[y] + 1) & 1; //更新re值 } int judge(int x, int y) { int nx = find_set(x), ny = find_set(y); if( nx == ny) //情况已知 return re[x] == re[y]; return 2; } void operation() { char op[5]; while( m --) { int a, b; scanf( "%s%d%d", op, &a, &b); if( 'A' == op[0]) { printf( "%s\n", ans[judge(a, b)]); } else union_set(a, b); } } int main() { int T; scanf( "%d", &T); while( T --) { scanf( "%d%d", &n, &m); init(); operation(); } return 0; }
浙公网安备 33010602011771号