enlaces a los temas: http://icpc.njust.edu.cn/Problem/Hdu/1272/
Sujeto obligado a soportar dos operaciones, una es una fusión, una es para eliminar la relación entre un punto y todos los demás puntos, pero el otro punto es claramente mantenimiento de la relación existente, problemas de relación involucra a nuestro pensamiento principal es comprobar y conjunto. relación operación de eliminación que puede hacer esto apunta a un nodo de nodos utilizados en la línea, pero si este nodo es la raíz de un árbol, entonces causará otros nodos de este árbol aún apunta a eliminar nodo. Por lo que necesitamos para crear un nodo virtual, el número 0-n-1 nodos de tiempo que comienza no apuntar a sí mismo, por lo que los nodos borrar directamente al nodo que se suprime el punto a un nuevo nodo puede, de mezcla y de eliminación son complejidad sustancialmente constante. Una cosa a destacar es que el registro de entrada y el enfoque en todos los nodos son los nodos tienen un padre, por lo que hay en la mayoría de m veces después de la eliminación de enlaces punto a punto a punto en sí tiempo de inicialización. Si no se establece, y luego encontrar (x) nunca llegar al padre de x.
Código es el siguiente:
1 #include <bits / STDC ++ h.> 2 usando espacio de nombres std; 3 typedef unsigned int ui; 4 typedef largo largo ll; 5 typedef unsigned largo largo ULL; 6 #define pf printf 7 #define mem (a, b) memset (a, b, sizeof (a)) 8 #define prime1 1E9 + 7 9 #define prime2 1E9 + 9 10 #define pi 3,14159265 11 #define LSON l, mediados, tr << 1 12 #define rson mitad + 1, r, rt << 1 | 1 13 #define Scand (x) scanf ( "% LLF", y x) 14 #define f (i, a, b) for (int i = a; i <= b; i ++) 15 #define de exploración (a) scanf ( "% d", y a) 16 #define pf (a, b) make_pair ((a), (b)) 17 #define P par <int, int> 18 #define dbg (args) cout << # args << ":" << args << endl; 19 #define inf 0x3f3f3f3f 20 const int maxN = 1300000 ; 21 int n, m, t; 22 int aa = 0 ; 23 int a, b; int > S; 25 int index; 26 int f [maxN]; 27 void init () 28 { 29 f (i, 0 , n- 1 ) f [i] = i + n; 30 f (i, n, 2 * n + m) f [i] = i; // 至多删除maxN个结点, 31 index = 2 * n; 32 s.clear (); 33 } 34 int find ( int x) 35 { 36 si (x == f [x]) de retorno x; 37 volver f [x] = encontrar (f [x]); 38 } 39 vacío Unión ( int x, int y) 40 { 41 int fx = find (x); 42 int fy = encontrar (y); 43 si (fx == fy) de retorno ; 44 otra cosa f [fx] = fy; 45 } 46 int main () 47 { 48 // freopen ( "input.txt", "r", la entrada estándar); 49 // freopen ( "output.txt", "w", stdout); 50 std :: ios :: sync_with_stdio (falso ); 51 Char tmp [ 5 ]; 52 , mientras que (scanf ( " % d% d " , y n, y m) == 2 && (n + m)) 53 { 54 aa ++ ; 55 init (); 56 f (i, 1 , m) 57 { 58 scanf ( " % s " , tmp); 59 Si (tmp [ 0 ] == ' M ' ) 60 { 61 de exploración (a); 62 de exploración (b); 63 Unión (a, b); 64 } 65 Si (tmp [ 0 ] == ' S ' ) 66 { 67 de exploración (a); 68 f [a] = índice ++ ; 69 } 70 } 71 f (i, 0 , n- 1 ) s.insert (find (i)); 72 pf ( " Caso #% d:% d \ n " , aa, s.size ()); 73 } 74 de retorno 0 ; 75 }