int main() { int cases,n,i,a,b,y,no,t = 0; char c; scanf("%d",&cases); while(cases--){ if(t != 0) printf("\n"); t++; scanf("%d",&n); for (i = 0; i <= n; i++) Make_Set(i); y = no = 0; getchar(); while(c = getchar(),c != EOF){ if(c == '\n') break; scanf(" %d %d",&a,&b); a = Find_Set(a); b = Find_Set(b); if(c == 'c') Union_Set(a,b); else if(c == 'q'){ if(a == b) y++; else no++; } else break; getchar(); } printf("%d,%d\n",y,no); } return 0; }
void Merge(int x, int y) { x = Find_Set(x), y = Find_Set(y); if(x == y) return; parent[x] = y; dist[x] = size[y]; size[y] += size[x]; }
// answers queries about whether two vertices are // in the same connected component int Same_Component(int u, int v) { if (Find_Set(u)==Find_Set(v)) { return true; } else { return false; } }
// compute the connected components of a graph void Connected_Components(void) { int i; for (i = 0; i < N; i++) { Make_Set(i); } for (i = 0; i < 7; i++) { if(Find_Set(E[i][0])!=Find_Set(E[i][1])) { Union(E[i][0],E[i][1]); } } }
// 合并 void Union(int x, int y) { x = Find_Set(x); y = Find_Set(y); if(x == y) // x,y在同一个集合 return; if(rank[x] > rank[y]) father[y] = x; else if(rank[x] < rank[y]) father[x] = y; else { rank[y]++; father[x] = y; } }
/* 查找x元素所在的集合,回溯时压缩路径*/ int Find_Set(int x) { if (x != father[x]) { father[x] = Find_Set(father[x]); //这个回溯时的压缩路径是精华 } return father[x]; }
/* Find_Set(S,x): determina o representante do elemento x. Pseudo-código no livro do Cormen et al */ int Find_Set(tdisjointset *S, int x) { /* Pseudo-code */ //if x != p[x] //then p[x] = Find_Set(p[x]) //return p[x] if(x != S->p) S->p = Find_Set(&S, S->p); return S->p; }
void Union(int x, int y) { x = Find_Set(x); y = Find_Set(y); if (x == y) return; if (rank[x] > rank[y]) { father[y] = x; } else { if (rank[x] == rank[y]) { rank[y]++; } father[x] = y; } }
void MST_Kruskal(struct vertex *G,int n,int E) { int i,j; struct edge *A[n-1],*temp,*e[E]; for(i=0;i<n;i++) Make_Set(G,i); for(i=0,j=0;i<n;i++) for(temp=G[i].edgep;temp;temp=temp->next) e[j++]=temp; Heap_Sort(e,E); for(i=0,j=0;i<E;i++) if(Find_Set(G,e[i]->start)!=Find_Set(G,e[i]->destin)) { A[j++]=e[i]; Union(G,e[i]->start,e[i]->destin); } Vertex_Detail_Prim(A,j); }
int Find_Set(int x) { if(x != parent[x]) { int tmp = parent[x]; parent[x] = Find_Set(parent[x]); dist[x] += dist[tmp]; } return parent[x]; }
int Find_Set(int x) { int tmp; if(x != parent[x]) { tmp = parent[x]; parent[x] = Find_Set(parent[x]); relation[x] = (relation[x] + relation[tmp]) % 3; } return parent[x]; }
int main() { freopen("t.in", "r", stdin); scanf("%d %d\n",&n,&k); for(int i = 1; i <= n; i ++) Make_Set(i); for(int i = 1, d, x, y; i <= k; i ++) { scanf("%d %d %d\n",&d,&x,&y); if(x > n || y > n || (d == 2 && x == y)) { cnt ++; continue; } int p = Find_Set(x), q = Find_Set(y); if(p != q) Union(x, y, d); else if((relation[y] + d + 2) % 3 != relation[x]) cnt ++; } printf("%d\n",cnt); }
int main() { freopen("t.in","r",stdin); scanf("%d", &m); int n = MAXN; for(int i = 1; i <= n; i ++) Make_Set(i); for(int i = 1; i <= m; i ++) { int a, b; char ctrl; scanf("\n%c %d", &ctrl, &a); if(ctrl == 'M') scanf("%d", &b); if(ctrl == 'M') Merge(a, b); else { Find_Set(a); printf("%d\n", dist[a]); } } }
int Find_Set(int x) { if (x != father[x]) father[x] = Find_Set(father[x]); return father[x]; }
void Union(int x, int y, int d) { int p = Find_Set(x), q = Find_Set(y); parent[p] = q; relation[p] = (relation[y] - relation[x] + d + 2) % 3; }
/* Union(S,x,y): faz a uniao das raizes das arvores de x e de y*/ void Union(tdisjointset *S, int x, int y) { /* Pseudo-code */ //Link(Find_Set(x),Find_Set(y)) Link(&S,Find_Set(&S, x),Find_Set(&S,y)); }
// returns a pointer to the representative of the (unique) set containing x struct elem* Find_Set(int x) { if (V[x]->key != x) V[x] = Find_Set(V[x]->key); return V[x]->rep; }
// 查找 int Find_Set(int x) { if(x != father[x]) x = Find_Set(father[x]); //路径压缩 return x; }