Cod sursa(job #1007882)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 9 octombrie 2013 20:42:19
Problema Cerere Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>

#define pb push_back


using namespace std;
const int Nmax = 100005;
queue<int> Q;
vector<int> G[ Nmax ];
int N,daddy[ Nmax ],stra[ Nmax ],root,D[ Nmax ];
    // tasu         al catalea stramos trebuie intrebat

void scan(int &A)
{
    char c = 0;A=0;
    do
    {
        c = fgetc(stdin);
        if('0'<=c && c<='9')
            A=A*10+c-48;
    }while('0'<=c && c<='9');
}

void read()
{
    scan(N);
    int i,a,b;
    for(i = 1 ; i <= N; ++i)
            scan(stra[ i ]);

    for(i = 1 ; i < N; ++i){
        scan(a);scan(b);
        G[a].pb(b);
        daddy[b] = a;
    }
    for(i = 1; i <= N; ++i)
        if(!daddy[i]) {
            root = i;
            break;
        }
}

int cauta(int k)
{
    int ns,nt=0;

    if(stra[ k ] == 0) //dak e eminent :)
        return 0;
    if(D[k] != -1) // dak am calc deja
        return D[k];

    while(D[k] == -1)
    {
        ns = stra[k];//la cati ne ducem in sus
        for(int i = 1; i <= ns; ++i)
            k = daddy[k];
        ++nt;
        if(D[k] != -1) return D[k]+nt;
        if(stra[k] == 0) return nt;
    }
}

void BFS(int nodc)//fiind un arbore si pronind din radacina
{                   // e clar ca nu ne trebuie sa marcam nodurile ca nu se poate
    Q.push(nodc);   // sa le bagi de mai multe ori decat trebuie
    while(!Q.empty())
    {
        nodc = Q.front();Q.pop();
        D[ nodc ] = cauta(nodc);// formam solutia
        for(vector<int>::iterator it = G[nodc].begin();it != G[nodc].end();++it)
            Q.push(*it);
    }
}

void solve()
{
    memset(D,-1,sizeof(D));
    BFS(root);
    for(int i = 1; i <= N ; ++i)
        printf("%d ",D[i]);
}

int main()
{
    freopen("cerere.in","r",stdin);
    freopen("cerere.out","w",stdout);

    read();
    solve();

    return 0;
}