Cod sursa(job #2889618)

Utilizator ioana11Nistor Ioana ioana11 Data 12 aprilie 2022 23:37:50
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.06 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n, m;
vector<pair<int, int>> queries;
map<int, vector<int>> fii;

vector<int> p_euler;
vector<int> niveluri;

void citire(){
    fin >> n >> m;
    
    int x, y;
    for(int i=2; i<=n; i++){
        fin >> x;

        // daca nodul x deja exista in map (dictionar),
        // inseamna ca fii[x] este deja un vector
        // asa ca putem da push in el
        if(fii.find(x) != fii.end()){
            fii[x].push_back(i);
        }
        else {
            // daca nu exista, vectorul trebuie creat
            // inainte de a da push
            vector<int> l;
            fii.insert(make_pair(x, l));
            fii[x].push_back(i);
        }
    }
    for(int i=1; i<=m; i++){
        fin >> x >> y;
        queries.push_back(make_pair(x, y));
    }
}

void print(vector<int> v){

    // echivalent python for x in v
    // trebuie declarat tipul de data al lui x
    // ! daca este complicat de dedus, pui auto
    // ! metoda se numeste iterare cu valoare/obiect ( ci nu cu index )
    for(int x : v){
        cout << x << " ";
    }
    cout << endl;
}

void dfs(int x, int nivel){ 
    p_euler.push_back(x);
    niveluri.push_back(nivel);

    // iteram in fii
    for(int fiu : fii[x]){ // echiv python: for fiu in fii
        dfs(fiu, nivel+1);

        // adaugam nodul sursa si intoarcerea din recursivitate
        p_euler.push_back(x);
        niveluri.push_back(nivel);
    }
}

int main(){
    citire();
    dfs(1, 0);
    // print(p_euler);
    // print(niveluri);
    for(auto query : queries){
    
        // vector<int> x;
        // x.push_back();
        // x.size(); -> punctul reprezinta accesarea unei
        //    !metode! sau unui !camp! dintr-un obiect
        // echivalent,
        // vecotr<int>::iterator
        // :: -> reprezinta accesarea unui !metode! sau unui !camp! dintrun !!!tip!!! de obiect
        
        
        // caut(find) nivelul minim din vectorul nivel, ( aflat intre q1 q2 )
        // pentru a afla indexul din p_euler care corespunde lca-ului
        vector<int>::iterator it1 = niveluri.begin() + (find(p_euler.begin(), p_euler.end(), query.first)-p_euler.begin());
        vector<int>::iterator it2 = niveluri.begin() + (find(p_euler.begin(), p_euler.end(), query.second)-p_euler.begin());
        // ^ find -> pointer la pozitia q1 in p_euler, din care scad p_euler.begin pentru a obtine index-ul
        // index-ul il adun in niveluri.begin() ca sa gasesc nivelul corespunzator lui in vectorul niveluri
        

        // caut elementul de la st la dr sau invers, intre elementele de mai sus
        // le gasesc index-ul
        if(it1 < it2){
            fout << p_euler[min_element(it1, it2) - niveluri.begin()];
        } else {
            fout << p_euler[min_element(it2, it1) - niveluri.begin()];
        }
        fout << endl;
             
    }

    return 0;
}


/*

2 3 4 5 6 7 8 9 10 11
1 1 2 2 2 4 4 6 3 3

fii: {
    1: [2, 3]
    2: []
}

d = {}
d["x"] = []
d.insert( (x, []) )

*/