Codeforces 1339D-Asignación de peso de borde (Estructura de datos-Árbol)

Descripción

Ideas

Siempre tengo algunas ideas sobre esta pregunta, pero no puedo escribirla. Tomó mucho tiempo leer la solución para entender. (Las siguientes imágenes son de la solución cf )

Cada nodo cuyo grado es mayor que 2 es el LCA de algunos nodos hoja. Deje que este nodo sea C en la figura. La línea punteada representa la ruta desde el nodo hoja hasta C, y todos los bordes sobre la ruta se fusionan en un borde. El peso de los bordes combinados es el XOR de los pesos de los bordes en el camino.
Imagen 1

Después de dicho procesamiento del árbol, un punto es un nodo hoja o un punto LCA (establecido en el punto C). Si es el punto C, entonces está conectado al nodo hoja u otro punto C.
De acuerdo con la intención de la pregunta, xor (ruta (hoja1, C)) == xor (ruta (hoja2, C)) == xor (ruta (raíz, C))
Dado que el punto C puede conectar múltiples nodos hoja, obviamente todas las rutas Los pesos de (leaf, C) son todos iguales, por lo que estos nodos de hoja se combinan en uno (es decir, leaf1 y leaf2 se pueden combinar en un nodo).

De esta manera, cualquier árbol puede transformarse en la forma de las siguientes figuras.
Discutir por situación

  1. Para la f más pequeña, siempre puede usar no más de 3 dígitos. Si la distancia entre cada par de puntos de hoja es par (es decir, la paridad de todos los puntos de hoja es par), entonces el mínimo f es 1, de lo contrario es 3.
    Imagen 2

  2. Para la f más grande, vea la figura y la solución del problema cf es fácil de conocer el establecimiento. El máximo f es el número de todos los lados menos (el número de puntos de hoja conectados por cada punto C (antes de la fusión) -1)
    Cuadro 3

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N = 1e5 + 10;
 
vector<int> np[N];
int cnt[N];
int p[N];
 
void dfs(int u, int fa, int par) {
    p[u] = par;
    for(auto v : np[u]) {
        if(v == fa) continue;
        dfs(v, u, par ^ 1);
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    for(int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        np[u].push_back(v);
        np[v].push_back(u);
        cnt[u]++;
        cnt[v]++;
    }
    
    int mn = 1, mx = n - 1;
    for(int i = 1; i <= n; i++) {
        if(cnt[i] == 1) {
            dfs(i, -1, 0);
            break;
        }
    }
    
    for(int i = 1; i <= n; i++) {
        if(cnt[i] == 1 && p[i] == 1) {
            mn = 3;
            break;
        } 
    }
    
    for(int i = 1; i <= n; i++) {
        int ch = 0;
        for(auto v : np[i]) {
            if(cnt[v] == 1) {
                ch++;
            }
        }  
        if(ch != 0)
            mx -= (ch - 1);
    }
    
    cout << mn << " " << mx << endl;
}

Supongo que te gusta

Origin www.cnblogs.com/limil/p/12690898.html
Recomendado
Clasificación