Luo Gu 1197 Star Wars

Lien de titre: https://www.luogu.com.cn/problem/P1197

Vous pouvez y penser à l'envers, ajouter progressivement des points à partir de l'état final et fusionner les points avec les points. Utilisez un cnt pour maintenir dynamiquement le nombre de blocs connectés: lorsqu'un nouveau point est ajouté, cnt ++, chaque fois que les ensembles sont fusionnés par la suite, si le nœud racine est dans le même ensemble, il ne sera pas fusionné et le cnt naturel ne changera pas; si le nœud racine est dans un ensemble différent Dans la fusion, le nombre de blocs connectés diminue de 1, cnt--.

Pour l'implémentation spécifique, j'ai ouvert plusieurs tableaux et utilisé la structure pour stocker les points gauche et droit de la route. P [i] = 0 signifie que le point i n'a pas été détruit. Un vecteur stocke les points adjacents à chaque point. Au début, fusionnez le dernier cas: si p [r [i] .x] = 0 et p [r [i] .y] = 0, puis fusionnez; puis suivez le processus ci-dessus d'ajout progressif de points, si les points nouvellement ajoutés Le point adjacent v [q [i]] [j] de q [i] n'est pas détruit, c'est-à-dire p [v [q [i]] [j]] = 0, puis fusionne q [i] et v [q [i ]] [j] et mettre à jour dynamiquement cnt.

1 #include <bits / stdc ++. H>
 2 en  utilisant l'  espace de noms std;
3  const  int maxn = 4000 + 10 ;
4  struct st { int x, y;} r [maxn];
5 vecteur < 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      pour (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 , taille de (p));
     pour (i = 1 ; i <= k; i ++ ) {
 22          int star; scanf ( " % d " , & star);
23          p [étoile] = 1 ; q [k-i + 1 ] = étoile;
24      }
 25      pour (i = 0 ; i <n; i ++) par [i] = i;
26      pour (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            si (xx! = yy) par [xx] = yy;
30        }
 31      s.clear ();
32      pour (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      pour (i = 1 ; i <= k; i ++ ) {
 39          p [q [i]] = 0 ; cnt ++ ;
40          pour (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! = Yy) {
 44                      par [xx] = yy; cnt-- ;
45                  }
 46             }
 47          ans [k-i + 1 ] = cnt;
48      }
 49      pour (i = 1 ; i <= k + 1 ; i ++) printf ( " % d \ n " , ans [i]);
50      //fclose (stdin); 
51      renvoie  0 ;
52 }
luogu1197

 

Je suppose que tu aimes

Origine www.cnblogs.com/edmunds/p/12752166.html
conseillé
Classement