Cod sursa(job #3357140)

Utilizator parus_majorParus Major parus_major Data 6 iunie 2026 17:07:37
Problema Cerere Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

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

const int MAXN = 100005;

int N;
int K[MAXN];
int tata[MAXN];
int ans[MAXN];
vector<int> graf[MAXN];
vector<int> drum; // Stiva care memorează calea de la rădăcină la nodul curent

void dfs(int nod) {
    drum.push_back(nod);
    int nivel_curent = drum.size() - 1;

    if (K[nod] == 0) {
        ans[nod] = 0;
    } else {
        // Al K-lea strămoș se află în istoria drumului
        int stramos = drum[nivel_curent - K[nod]];
        ans[nod] = 1 + ans[stramos];
    }

    // Continuăm DFS pentru fii
    for (int fiu : graf[nod]) {
        dfs(fiu);
    }

    // Eliminăm nodul curent la întoarcerea din recursivitate
    drum.pop_back();
}

int main() {
    // Optimizare input/output
    ios_base::sync_with_stdio(false);
    fin.tie(NULL);

    if (!fin) return 0;

    fin >> N;
    for (int i = 1; i <= N; ++i) {
        fin >> K[i];
    }

    for (int i = 1; i < N; ++i) {
        int u, v;
        fin >> u >> v;
        graf[u].push_back(v);
        tata[v] = u; // Marcăm tatăl lui v pentru a găsi rădăcina
    }

    // Găsim rădăcina arborelui (nodul care nu are tată)
    int radacina = 1;
    for (int i = 1; i <= N; ++i) {
        if (tata[i] == 0) {
            radacina = i;
            break;
        }
    }

    // Pornim parcurgerea din rădăcină
    dfs(radacina);

    // Afișarea rezultatelor
    for (int i = 1; i <= N; ++i) {
        fout << ans[i] << (i == N ? "" : " ");
    }
    fout << "\n";

    return 0;
}