Cod sursa(job #1760498)

Utilizator preda.andreiPreda Andrei preda.andrei Data 20 septembrie 2016 21:13:27
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int kNoduriNivel = 350;

struct Nod
{
    int nivel;
    int adancime;
    int stramos;
};

vector<int> SorteazaTopologic(const vector<int> &t, const vector<bool> &f)
{
    vector<int> ordine;
    queue<int> q;

    for (int i = 1; i < t.size(); ++i) {
        if (f[i])
            q.push(i);
    }

    while (!q.empty()) {
        ordine.push_back(q.front());
        if (t[q.front()] > 0)
            q.push(t[q.front()]);
        q.pop();
    }

    return ordine;
}

vector<Nod> ConstruiesteArbore(const vector<int> &tati, const vector<bool> &frunza)
{
    auto ordine = SorteazaTopologic(tati, frunza);
    vector<Nod> arbore(tati.size());

    for (int i = ordine.size() - 1; i >= 0; --i) {
        int curent = ordine[i];

        if (tati[curent] == 0) {
            arbore[curent] = {1, 1, 0};
        }
        else {
            arbore[curent].nivel = arbore[tati[curent]].nivel;
            arbore[curent].adancime = arbore[tati[curent]].adancime + 1;
            arbore[curent].stramos = arbore[tati[curent]].stramos;
            if (arbore[curent].adancime > kNoduriNivel) {
                ++arbore[curent].nivel;
                arbore[curent].adancime = 1;
                arbore[curent].stramos = tati[curent];
            }
        }
    }

    return arbore;
}

int AflaStramos(const vector<Nod> &arbore, const vector<int> &tati, int start, int k)
{
    while (start > 0 && k > arbore[start].adancime) {
        k -= arbore[start].adancime;
        start = arbore[start].stramos;
    }

    while (start > 0 && k > 0) {
        start = tati[start];
        --k;
    }

    return start;
}

int main()
{
    ifstream fin("stramosi.in");
    ofstream fout("stramosi.out");

    int n, m;
    fin >> n >> m;

    vector<int> tati(n + 1);
    vector<bool> este_frunza(n + 1, true);

    for (int i = 1; i <= n; ++i) {
        fin >> tati[i];
        este_frunza[tati[i]] = false;
    }

    auto arbore = ConstruiesteArbore(tati, este_frunza);

    while (m--) {
        int x, y;
        fin >> x >> y;
        fout << AflaStramos(arbore, tati, x, y) << "\n";
    }

    return 0;
}