제출 #1350276

#제출 시각아이디문제언어결과실행 시간메모리
1350276GabrielLOSTIKS (INOI20_lostiks)C++20
0 / 100
0 ms344 KiB
#include "bits/stdc++.h"
using namespace std;
vector< vector< pair<int, int> > > Grafo;
vector<int> Distancias, _rbol, Primero, Requerimentos, Arreglo, Inicio;
map<int, int> Mapeo;
void DFS(int Nodo, int Se_necesita){
    //cerr<<Nodo<<" ";
    Requerimentos[Nodo] = Se_necesita;
    Primero[Nodo] = int(Arreglo.size());
    Arreglo.push_back(Distancias[Nodo]);
    for(auto E: Grafo[Nodo]){
        if(Distancias[E.first] <= Distancias[Nodo] + 1) continue;
        Distancias[E.first] = Distancias[Nodo] + 1;
        //Anteriores[E.first] = Nodo;
        int Requisito = Se_necesita;
        if(E.second != -2){
            Requisito = E.second;
            Inicio[Mapeo[E.second]] = Nodo;
        }
        DFS(E.first, Requisito);
        Arreglo.push_back(Distancias[Nodo]);
    }
}
void Crear(int i, int d, int p){
    if(i == d){
        _rbol[p] = Arreglo[i];
        return;
    }
    int P = (i + d) / 2;
    Crear(i, P, p * 2);
    Crear(P + 1, d, p * 2 + 1);
    _rbol[p] = min(_rbol[p * 2], _rbol[p * 2 + 1]);
}
int Consulta(int i, int d, int p, int I, int D){
    if(i >= I and d <= D) return _rbol[p];
    if(i > D or d < I) return 2222222;
    int P = (i + d) / 2;
    return min(Consulta(i, P, p * 2, I, D), Consulta(P + 1, d, p * 2 + 1, I, D));
}
deque< pair<int, int> > Llaves_ordenadas;
bitset<22> Obtenido, En_progreso;
bool Mal = 0;
void Obtener_llaves(int Actual){
    if(Actual == -2 or Mal) return;
    if(Obtenido[Actual]) Obtener_llaves(Requerimentos[Actual]);
    Llaves_ordenadas.push_front({Actual, Inicio[Mapeo[Actual]]});
    int Siguiente = Requerimentos[Inicio[Mapeo[Actual]]];
    En_progreso[Actual] = 1;
    if(Siguiente != -2){
        if(En_progreso[Siguiente]){
            Mal = 1;
            return;
        }
        Obtener_llaves(Siguiente);
    }
    En_progreso[Actual] = 0;
    Obtenido[Actual] = 1;
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, i, f;
    cin>>n>>i>>f;
    i--;
    f--;
    Grafo.assign(n, {});
    Distancias.assign(n, 2222222);
    Primero.assign(n, 0);
    Requerimentos.assign(n, -2);
    Distancias[i] = 0;
    set<int> Llaves;
    if(i == f){
        cout<<0;
        return 0;
    }
    for(int a = 0; a < n - 1; a++){
        int u, v, t;
        cin>>u>>v>>t;
        u--;
        v--;
        t--;
        if(t == -1) t--;
        else Llaves.insert(t);
        Grafo[u].push_back({v, t});
        Grafo[v].push_back({u, t});
    }
    int ID = 0;
    for(auto E: Llaves){
        Mapeo[E] = ID;
        ID++;
    }
    Inicio.assign(ID, -2);
    //cerr<<"Nodos.\n";
    DFS(i, -2);
    /*cerr<<"\nRequerimentos.\n";
    for(auto E: Requerimentos) cerr<<E<<" ";*/
    int m = int(Arreglo.size());
    _rbol.assign(m * 4 + 22, 0);
    Crear(0, m - 1, 1);
    Obtener_llaves(Requerimentos[f]);
    /*cerr<<"\nLlaves.\n";
    for(auto E: Llaves_ordenadas) cerr<<E.first<<" ";
    cerr<<"\n";
    for(auto E: Llaves_ordenadas) cerr<<E.second<<" ";
    cerr<<"\n";*/
    if(Mal){
        cout<<-1;
        return 0;
    }
    long long r = 0;
    for(auto E: Llaves_ordenadas){
        r += Distancias[i] + Distancias[E.first] - 2 * Consulta(0, m - 1, 1, min(Primero[i], Primero[E.first]), max(Primero[i], Primero[E.first]));
        i = E.first;
        r += Distancias[i] + Distancias[E.second] - 2 * Consulta(0, m - 1, 1, min(Primero[i], Primero[E.second]), max(Primero[i], Primero[E.second]));
        i = E.second;
    }
    cout<<r + Distancias[i] + Distancias[f] - 2 * Consulta(0, m - 1, 1, min(Primero[i], Primero[f]), max(Primero[i], Primero[f]));
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...