Pagini recente » Cod sursa (job #3315028) | Cod sursa (job #3317433) | Cod sursa (job #3329490) | Cod sursa (job #180657) | Cod sursa (job #3341199)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("cerere.in");
ofstream out("cerere.out");
const int MAX=100005;
vector<int>V(MAX);
vector<vector<int>>graf(MAX);
vector<int>dp(MAX);
vector<bool>viz(MAX);
vector<int>sol(MAX);
vector<int>tata(MAX);
void solve(int nod,int niv){
dp[niv]=nod;
if(!V[nod]){
sol[nod]=0;
}else if(niv-V[nod]>=1){
sol[nod]=sol[dp[niv-V[nod]]]+1;
}else{
sol[nod]=0;
}
for(auto v : graf[nod]){
solve(v,niv+1);
}
}
int main(){
int n,x,y;
in>>n;
int r;
for(int i=1;i<=n;i++){
in>>V[i];
}
for(int i=1;i<n;i++){
in>>x>>y;
graf[x].push_back(y);
tata[y]=x;
}
for(int i=1;i<=n;i++){
if(!tata[i]){
r=i;
break;
}
}
solve(r,1);
for(int i=1;i<=n;i++){
out<<sol[i]<<" ";
}
}
/*
===========================================================================
PROBLEMA: CERERE - EXPLICAȚIE LOGICĂ (DFS + DP PE STIVĂ)
===========================================================================
1. CE REPREZINTĂ VECTORII TĂI:
------------------------------
- V[nod]: Al câtelea strămoș trebuie să primească cererea (K_i din enunț).
- dp[niv]: "Stiva" care reține ce nod se află la fiecare nivel de adâncime.
(Ex: dp[1] e rădăcina, dp[2] e fiul ei, etc.)
- sol[nod]: Răspunsul final (numărul de maimuțe prin care trece cererea).
2. MECANISMUL DE REZOLVARE (Funcția solve):
-------------------------------------------
A) ÎNREGISTRAREA NODULUI:
- Când intri într-un nod la nivelul 'niv', îl salvezi în dp[niv] = nod.
- Astfel, orice nod știe cine sunt toți strămoșii lui uitându-se în 'dp'.
B) CALCULUL PRIN PROGRAMARE DINAMICĂ:
- CAZ 1 (V[nod] == 0): Maimuța e inteligentă, rezolvă ea. sol[nod] = 0.
- CAZ 2 (Există al K-lea strămoș):
- Îl găsești imediat: stramos = dp[niv - V[nod]].
- Aplici recurența: sol[nod] = sol[stramos] + 1.
- (+1 reprezintă maimuța 'stramos' care primește cererea).
C) PARCURGEREA:
- Mergi recursiv la toți fiii. Deoarece este arbore și mergi de la tată
la fiu, nu ai nevoie de vectorul 'viz' (nu te poți întoarce).
3. GĂSIREA RĂDĂCINII:
---------------------
- Deoarece în fișierul de intrare nu se spune mereu că nodul 1 e rădăcina,
ai folosit vectorul 'tata'. Nodul care nu are tată (tata[i] == 0) este
rădăcina arborelui de la care pornești DFS-ul.
4. COMPLEXITATE:
----------------
- Timp: O(N) - Vizitezi fiecare nod o singură dată.
- Memorie: O(N) - Pentru stocarea arborelui și a vectorilor auxiliari.
===========================================================================
*/