Enlace del título: https://www.luogu.com.cn/problem/P1197
Puede pensarlo al revés, y gradualmente agregar puntos desde el estado final, y fusionar los puntos con los puntos. Use un cnt para mantener dinámicamente el número de bloques conectados: cuando se agrega un nuevo punto, cnt ++, cada vez que se fusiona la colección, si el nodo raíz está en el mismo conjunto, no se fusionará, naturalmente el cnt no cambiará; si el nodo raíz está en un conjunto diferente En la fusión, el número de bloques conectados disminuye en 1, cnt--.
Para la implementación específica, abrí varias matrices y usé la estructura para almacenar los puntos izquierdo y derecho del camino. P [i] = 0 significa que el punto i no ha sido destruido. Q [i] almacena el orden de los puntos en orden inverso. Ans almacena la respuesta en orden inverso, y luego usa Un vector almacena los puntos adyacentes a cada punto. Al principio, combine el último caso: si p [r [i] .x] = 0 y p [r [i] .y] = 0, luego combine; luego siga el proceso anterior de agregar puntos gradualmente, si los puntos recién agregados El punto adyacente v [q [i]] [j] de q [i] no se destruye, es decir, p [v [q [i]] [j]] = 0, luego combina q [i] y v [q [i] ]] [j] y actualiza dinámicamente cnt.
1 #include <bits / stdc ++. H> 2 usando el espacio de nombres std; 3 const int maxn = 4000 + 10 ; 4 struct st { int x, y;} r [maxn]; 5 vector < int > v [maxn]; 6 int p [maxn], par [maxn], q [maxn], ans [maxn]; 7 int n, m, i, j, k, t; 8 set < int > s; 9 10 int find ( int u) { return par [u] == u? U: par [u] = find (par [u]);} 11 12 int main () { 13 // freopen ("luogu1197.txt", "r", stdin); 14 scanf ( " % d% d " , & n, & m); 15 para (i = 1 ; i <= m; i ++ ) { 16 scanf ( " % d% d " , & r [i] .x, & r [i] .y); 17 v [r [i] .x] .push_back (r [i] .y); v [r [i] .y] .push_back (r [i] .x); 18 } 19 scanf ( " % d " , & k); 20 memset (p, 0 , sizeof (p)); para (i = 1 ; i <= k; i ++ ) { 22 int star; scanf ( " % d " , & star); 23 p [estrella] = 1 ; q [k-i + 1 ] = estrella; 24 } 25 para (i = 0 ; i <n; i ++) par [i] = i; 26 para (i = 1 ; i <= m; i ++ ) 27 if (p [r [i] .x] == 0 && p [r [i] .y] == 0 ) { 28 int xx = find (r [i] .x); int yy = find (r [i] .y); 29 if (xx! = aa) par [xx] = aa; 30 } 31 s.clear (); 32 para (i = 0 ; i <n; i ++ ) { 33 par [i] = find (par [i]); 34 if (p [i] == 0 ) s.insert (par [i]); 35 } 36 int cnt = s.size (); 37 ans [k + 1 ] = cnt; 38 para (i = 1 ; i <= k; i ++ ) { 39 p [q [i]] = 0 ; cnt ++ ; 40 para (j = 0; j <v [q [i]]. size (); j ++ ) 41 if (p [v [q [i]] [j]] == 0 ) { 42 int xx = find (q [i]); int yy = find (v [q [i]] [j]); 43 if (xx! = Aa) { 44 par [xx] = aa; cnt-- ; 45 } 46 } 47 ans [k-i + 1 ] = cnt; 48 } 49 para (i = 1 ; i <= k + 1 ; i ++) printf ( " % d \ n " , ans [i]); 50 //fclose (stdin); 51 devuelve 0 ; 52 }