PAT Clase A 1143 Ascendencia común mínima

Enlace al título original

El ancestro común más bajo (LCA) de dos nodos U y V en un árbol es el nodo más profundo que tiene tanto a U como a V como descendientes.

Un árbol de búsqueda binaria (BST) se define recursivamente como un árbol binario con las siguientes propiedades:

Si su subárbol izquierdo no está vacío, los valores de todos los nodos del subárbol izquierdo son menores que el valor de su nodo raíz
Si su subárbol derecho no está vacío, los valores de todos los nodos del subárbol derecho son mayores que o Es igual al valor de su nodo raíz.
Sus subárboles izquierdo y derecho también son árboles de búsqueda binarios.
Ahora, dados dos nodos cualesquiera en BST, encuentre su ancestro común más bajo.

Formato de entrada
La primera línea contiene dos números enteros M y N, que representan respectivamente el número de pares de nodos de consulta y el número de nodos en el árbol de búsqueda binaria.

La segunda fila contiene N números enteros diferentes, que representan la secuencia transversal previa al pedido del árbol de búsqueda binaria.

Las siguientes M líneas, cada una de las cuales contiene dos números enteros U y V, representan un conjunto de consultas.

Todos los pesos de los nodos están en el rango de int.

Formato de salida
Para cada par dado de U y V, genera una línea de resultados.

Si el LCA de U y V es A, y A no es U ni V, el LCA de U y V es A.

Si el LCA de U y V es A, y A es U o V, entonces la salida X es un ancestro de Y, donde X representa A e Y representa el otro nodo.

Si no se encuentra U o V en el BST, se emite ERROR: no se encuentra U. o ERROR: no se encuentra V. o ERROR: no se encuentran U y V.

Rango de datos
1≤M≤1000,
1≤N≤10000
Ejemplo de entrada:
6 8
6 3 1 2 5 4 8 7 2
5
8 7
1 9
12 -3
0 8
99 99
Ejemplo de salida:
LCA de 2 y 5 es 3.
8 es un ancestro de 7.
ERROR: no se encuentra 9.
ERROR: no se encuentran 12 y -3.
ERROR: no se encuentra 0.
ERROR: no se encuentran 99 y 99.

Mi solución:

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int m, n;
int pre[N], in[N], f[N], dep[N];
unordered_map <int, int> pos;

int build(int il, int ir, int pl, int pr, int d){
    int root = pre[pl];
    int k = pos[root];
    dep[root] = d;
    
    if(il < k) f[build(il, k - 1, pl + 1, pl + 1 + k - 1 - il, d + 1)] = root;
    if(k < ir) f[build(k + 1, ir, pl + 1 + k - il, pr, d + 1)] = root;
    
    return root;
}
int main(){
    cin >> m >> n;
    for(int i = 0; i < n; i ++ ){
        cin >> pre[i];
        in[i] = pre[i];
    }
    
    sort(in, in + n);
    
    for(int i = 0; i < n; i ++ ){
        pos[in[i]] = i;
    }
    
    int d = 0;
    build(0, n - 1, 0, n - 1, d);
    
    while(m -- ){
        int u, v;
        cin >> u >> v;
        if(pos.count(u) && pos.count(v)){
            int a = u, b = v;
            
            while(a != b){
                if(dep[a] > dep[b]) a = f[a];
                else b = f[b];
            }
            if(a != u && a != v) printf("LCA of %d and %d is %d.\n", u, v, a);
            else if(u == a) printf("%d is an ancestor of %d.\n", a, v);
            else printf("%d is an ancestor of %d.\n", a, u);
            
        }
        else if(pos.count(u) == 0 && pos.count(v) == 0) 
            printf("ERROR: %d and %d are not found.\n", u, v);
        else if(pos.count(u) == 0)
            printf("ERROR: %d is not found.\n", u);
        else if(pos.count(v) == 0)
            printf("ERROR: %d is not found.\n", v);
    }

    return 0;
}

premio:

Para construir un árbol binario, no es necesario construir el árbol completamente, de acuerdo con las condiciones requeridas, puede crear f [ ] -> guardar el nodo padre de cada nodo, o crear l [ ] r[ ] -> guardar el hijos izquierdo y derecho de cada nodo. (Lo mismo se aplica a los árboles múltiples)

Supongo que te gusta

Origin blog.csdn.net/weixin_45660485/article/details/126085729
Recomendado
Clasificación