Question:
There are N Gears, three operations
1. Operation L x Y: link the gears X and Y. If X and Y are already in a gear group, the two groups will also be merged.
2. Perform the q x y operation to check whether the rotation direction of X and Y is the same (equivalent to the parity of the relative distance of X and Y ).
3. Operation d x: remove the gear X and the gear group where X is located will not be disconnected.
4. Operation S x: query the number of gears in the gear group where gear X is located.
While maintaining the parent node, DIS records the distance between each node and the root node, and uses num to record the number of elements in the set where X is the root node.
Due to the deletion operation, deleting the root node will lead to information loss. Therefore, a new node is directly created during the deletion, so a variable is added, the actual node number MP [x] corresponding to node X.
In this way, Fa [x] indicates the parent node of X, and MP [x] indicates the actual number of X (starting from n + 1)
(Copied)
Code:
# Include <iostream> # include <cstdio> # include <cstring> # include <cmath> # include <cstdlib> # include <algorithm> using namespace STD; # define n 600007 # define M 33int Fa [N], n, m, DIS [N]; int num [N], MP [N]; int findset (int x) {If (X! = Fa [x]) {int TMP = findset (Fa [x]); DIS [x] + = dis [Fa [x]; // accumulative distance Fa [x] = TMP;} return Fa [X];} void Init () {for (INT I = 0; I <= N + m; I ++) {Fa [I] = I; num [I] = 1; DIS [I] = 0; MP [I] = I ;}} int main () {int I, u, v, k; char ss [5]; while (scanf ("% d", & N, & M )! = EOF) {Init (); int now = n + 1; while (M --) {scanf ("% s", SS ); if (ss [0] = 'l') {scanf ("% d", & U, & V); U = MP [u]; // The actual position v = MP [v]; int FX = findset (U); int FY = findset (V); If (FX! = FY) {Fa [FX] = FY; // dis [FX] = dis [FY] + 1; // 1 // dis [u] = dis [v] + 1; // The Order of 2 ** 1 and 2 cannot be reversed, alternatively, use the following ** dis [FX] = dis [u] + dis [v] + 1; // parity of the sum of the root distance to reverse it, obtain the parity of relative distance num [FY] + = num [FX] ;}} else if (ss [0] = 'q ') {scanf ("% d", & U, & V); U = MP [u]; // the actual position v = MP [v]; int FX = findset (U); int FY = findset (V); If (FX! = FY) puts ("unknown"); else {If (ABS (DIS [u]-Dis [v]) & 1) puts ("different "); else puts ("same") ;}} else if (ss [0] = 's') {scanf ("% d", & U ); int Tu = MP [u]; printf ("% d \ n", num [findset (TU)]);} else {scanf ("% d", & V ); int TV = MP [v]; num [findset (TV)] --; MP [v] = now ++ ;}} return 0 ;}
View code