Friends (Flip Tree Edge Weight Game) -Todavía pensando

Jun B está mirando a un grupo de niños y un grupo de niñas jugando juegos. Específicamente, el juego es así:
dado un árbol de n nodos, cada borde de este árbol tiene un peso. Este peso solo puede ser 0 o 1) Al comienzo de un juego, se determinará un nodo como raíz. Luego, comenzando por la niña, las dos partes se turnan para operar.
Cuando una de las partes opera, primero debe seleccionar un punto que no sea una raíz, para asegurarse de que el peso del borde desde ese punto hasta su padre sea 1; luego encuentre una ruta simple desde este punto hasta el nodo raíz y voltee el peso de todos los bordes en el camino ( Es decir, 0 se convierte en 1 y 1 se convierte en 0).
Cuando un lado no puede operar (es decir, todos los pesos laterales son 0), el otro lado gana.
Si ambas partes adoptan la estrategia óptima, la niña ganará, luego emitirá "¡Las niñas ganan!", De lo contrario, saldrá "¡Los niños ganan!"
Para hacer que el juego sea más interesante, puede haber operaciones para modificar el poder del borde entre cada ronda, y el nodo raíz especificado para cada ronda del juego también puede ser diferente.
Específicamente, hay m operaciones para modificar el peso del borde y jugar el juego, de la siguiente manera:
"0 x" significa preguntar qué parte ganará si el árbol actual comienza con x como el nodo raíz.

"1 xyz" significa modificar el peso del borde entre x e y a z.
¡Por supuesto, Jun B sabe cómo hacerlo! Pero él quiere ponerte a prueba.
La entrada contiene hasta 5 conjuntos de datos de prueba.
La primera línea tiene un número entero positivo que indica el número de grupos de datos.
A continuación, en la primera línea de cada grupo de datos, hay dos enteros positivos n y m separados por dos espacios, que representan el número de puntos y el número de operaciones. Asegúrese de que n, m <40000.
Las siguientes n-1 filas, cada fila de tres enteros x, y, z, representan un borde del árbol. Asegúrese de que 1 <x <n, 1 <y <n, 0 <= z <= 1.
Las siguientes m líneas, una operación por línea, el significado es como se describió anteriormente. Se garantiza que solo aparecerán los dos formatos mencionados anteriormente.
Para la operación 0, asegúrese de 1 <= x <= n; para la operación 1, asegúrese de 1 <= x <= n, 1 <= y <= n, 0 <= z <= 1, y asegúrese de que haya una conexión de borde x en el árbol E y.
Salida Para cada operación de consulta de cada conjunto de datos, envíe una línea de "¡Los niños ganan!" O "Las niñas ganan!" Entrada de muestra
2 
2 3 
1 2 0 
0 1 
1 2 1 1 
0 2 
4 11 
1 2 1 
2 3 1 
3 4 0 
0 1 
0 2 
0 3 
0 4 
1 2 1 0 
0 1 
0 2 
0 3 
1 3 4 1 
0 3 
0 4 4
Salida de muestra
Gana muchachos! 
Chicas ganar! 
Chicas ganar! 
Niños ganar! 
Chicas ganar! 
Niños ganar! 
Niños ganar! 
Chicas ganar! 
Chicas ganar! 
Niños ganar! 
Chicas ganar! 
Ideas:
Para esta pregunta similar, sabemos que debe haber una ley oculta.
Lo principal es mirar el borde del árbol directamente conectado al nodo raíz.
①Si solo hay un borde conectado al nodo raíz , llamamos a este borde X.
  1. Entonces pensamos que si el peso del lado X es 1: la
    primera mano puede ignorar el lado detrás de X y solo girar X a 0, incluso si la siguiente persona da la espalda para poder girar el borde, entonces X se convierte nuevamente en 1 , De modo que no importa de qué lado la otra persona se vuelva atrás, la primera mano solo puede girar X, consumiendo a la otra persona, hasta que la parte posterior de X sea todo 0, y luego girar X, la primera mano gana.
  2. Por el contrario, el peso del lado X es 0: la
   primera mano solo puede girar el lado detrás de X, y la otra persona (mano de atrás) puede imitar la primera mano de la situación anterior, y la mano de atrás gana.
② De manera similar, nos conectaremos directamente al nodo raíz, y el peso del borde es 1 para expandirlo a varios bordes , colectivamente denominado X:
  1. Si el número de X es impar, primera y segunda mano (una cadena y una cadena) ) Consumo del oponente por turno, al final una cadena con X sigue girando primero X y gana primero (simulado ①1.)
  2. Del mismo modo, el número de X es par, la primera y segunda mano (una cadena y una cadena) se consumen entre sí, Al final, una cadena con X es que la mano de atrás gira X primero, y la mano de atrás gana (imita ① 2.)
  Nota: (En ②, no discutimos el borde directamente conectado al nodo raíz como ①, el peso del borde es 0, porque si el borde detrás de este borde tiene un valor de 1, después de la primera vuelta,
  este está directamente conectado a El borde del nodo raíz se convierte en 1, y el revés puede usarlo para consumir al oponente. Cuando el revés gana, es equivalente a cuando X es 0, es decir, el número de X es par, igual que ② 2. Conclusión)
Resumen:
  solo necesitamos ver Si hay varios pesos de borde directamente conectados al nodo raíz, el ganador que comienza el juego con este nodo como el nodo raíz puede ser juzgado, impar-> primera mano gana par-> última mano gana .
Código:
1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5  usando el  espacio de nombres std;
6  const  int maxn = 4e4 + 3 ;
7  int head [maxn], n, m, cnt, clave;
8  int x, y, z;
9  struct Edge { bool wei; int to, next;} e [ 2 * maxn];
10  void Add ( int x, int y, int z) {
 11      e [++ cnt] .to =y;
12      if (z) e [cnt] .wei = 1 ; de lo contrario e [cnt] .wei = 0 ;
13      e [cnt] .next = cabeza [x];
14      cabeza [x] = cnt;
15  }
 16  nulo Xiugai ( int x, int y, int z) {
 17      for ( int i = head [x]; i; i = e [i] .next) {
 18          if (y == e [i]. a) {
 19              if (z) e [i] .wei = 1 ; de lo contrario e [i] .wei = 0 ;
20              descanso;
21          }
 22      }
 23      para ( int i = head [y]; i; i = e [i] .next) {
 24          if (x == e [i] .to) {
 25              if (z) e [i] .wei = 1 ; de lo contrario e [i] .wei = 0 ;
26              regreso ;
27          }
 28      }
 29  }
 30  vo Sta ( int raíz) {
 31      int ans = 0 ;
32      para ( int i = head [root]; i; i = e [i] .next) {
33          if (e [i] .wei) ans ++ ;
34      }
 35      if (ans% 2 == 1 ) printf ( "¡Las chicas ganan! \ N " );
36      más printf ( "¡Los chicos ganan! \ N " );
37  }
 38  int main () {
 39  //     freopen ("1.in", "r", stdin); 
40      int t;    
41      scanf ( " % d " , & t);
42      while (t-- ) {
 43          cnt = 0; memset (head, 0 , sizeof (head));
44          scanf ( " % d% d " , & n, & m);
45          para ( int i = 1 ; i <n; ++ i) {
 46              scanf ( " % d% d% d " , & x, & y, & z);
47              Agregar (x, y, z); Agregar (y, x, z);
48          }
 49          para ( int i = 1 ; i <= m; ++ i) {
 50              scanf ( " % d " , & clave);
51             if ( tecla ! ) {
 52                  scanf ( " % d " , & x);
53                  Sta (x);
54              } else {
 55                  scanf ( " % d% d% d " , & x, & y, & z);
56                  Xiugai (x, y, z);
57              }
 58          }
 59      }
 60      devuelve  0 ;
61 }

 

Supongo que te gusta

Origin www.cnblogs.com/Lour688/p/12688771.html
Recomendado
Clasificación