【ACWing】 323. Juego de estrategia

Dirección del asunto:

https://www.acwing.com/problem/content/325/

A Bob le gusta jugar juegos de computadora, especialmente juegos de estrategia, pero a veces no puede encontrar una solución al problema, lo que lo entristece mucho. Ahora tiene los siguientes problemas. Debe proteger una ciudad medieval cuyos caminos constituyen un árbol. Los soldados de cada nodo pueden observar todos los bordes conectados a este punto. Debe colocar un número mínimo de soldados en los nodos para que puedan observar todos los bordes. ¿Puedes ayudarlo?

Formato de entrada: la
entrada contiene varios conjuntos de datos de prueba y cada conjunto de datos de prueba se utiliza para describir un árbol. Para cada conjunto de datos de prueba, la primera fila contiene un número entero NNN representa el número de nodos del árbol. SiguienteNNN líneas, cada línea describe un nodo de la siguiente manera.
Número de nodo: (número de subnodos) subnodo subnodo ... El
número de nodo comienza desde0 00 aN - 1 N − 1N - 1 , el número de nodos secundarios de cada nodo no supera los10 101 0 , cada borde solo aparece una vez en los datos de entrada.

Formato de salida:
para cada conjunto de datos de prueba, envíe un resultado que ocupe una línea, indicando el número mínimo de soldados requeridos.

Rango de datos:
0 <N ≤ 1500 0 <N≤15000<norte1 5 0 0

La idea es programación dinámica. Sea f [i] [0, 1] f [i] [0,1]f [ i ] [ 0 ,1 ] Respectivamente esiiEn el subárbol con i como raíz,iino se tomayo Watoriiii En ambos casos, el número mínimo de soldados requerido respectivamente. DejaiiLos hijos de i sonx 1, ..., xn x_1, ..., x_nX1,. . . ,Xn, Al buscar f [i] [0] f [i] [0]Cuando f [ i ] [ 0 ] , porqueiii no se toma, por lo que todos sus hijos deben tomarse para garantizar(i, x 1, ..., n) (i, x_ {1, ..., n})( yo ,X1 , . . . , n) Estos bordes están cubiertos, entonces: f [i] [0] = ∑ 1 ≤ k ≤ nf [xk] [1] f [i] [0] = \ sum_ {1 \ le k \ le n} f [x_k ] [1]f [ i ] [ 0 ]=1 k nΣf [ xk] [ 1 ] Al buscarf [i] [0] f [i] [0]Cuando f [ i ] [ 0 ] , porqueiii se toma, por lo que cada uno de sus hijos se puede tomar o no, por lo que hay: f [i] [1] = 1 + ∑ 1 ≤ k ≤ n max ⁡ {f [xk] [0], f [xk] [1]} f [i] [1] = 1 + \ sum _ {1 \ le k \ le n} \ max \ {f [x_k] [0], f [x_k] [1] \}f [ i ] [ 1 ]=1+1 k nΣmax { f [ xk] [ 0 ] ,f [ xk] [ 1 ] } El código es el siguiente:

#include <iostream>
#include <cstring>
using namespace std;

const int N = 1510;

int n;
int h[N], e[N], ne[N], idx;
int f[N][2];
bool is_root[N];

void add(int a, int b) {
    
    
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs(int u) {
    
    
    int c0 = 0, c1 = 1;
    for (int i = h[u]; ~i; i = ne[i]) {
    
    
        int j = e[i];
        dfs(j);

        c0 += f[j][1];
        c1 += min(f[j][0], f[j][1]);
    }

    f[u][0] = c0;
    f[u][1] = c1;
}

int main() {
    
    
    while (scanf("%d", &n) != -1) {
    
    
    	// 重置一下各个数组
        memset(h, -1, sizeof h);
        memset(is_root, true, sizeof is_root);
        memset(f, 0, sizeof f);
        idx = 0;

        for (int i = 0; i < n; i++) {
    
    
            int id, cnt;
            scanf("%d:(%d)", &id, &cnt);
            for (int j = 0; j < cnt; j++) {
    
    
                int a;
                cin >> a;
                add(id, a);
                is_root[a] = false;
            }
        }

        for (int i = 0; i < n; i++)
            if (is_root[i]) {
    
    
                dfs(i);
                cout << min(f[i][0], f[i][1]) << endl;
                break;
            }
    }

    return 0;
}

Complejidad temporal y espacial de cada conjunto de datos O (N) O (N)O ( N )

Supongo que te gusta

Origin blog.csdn.net/qq_46105170/article/details/114778045
Recomendado
Clasificación