Cod sursa(job #47153)

Utilizator vlad_popaVlad Popa vlad_popa Data 3 aprilie 2007 13:09:55
Problema Cerere Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <cstdio>
#include <string>

#define FIN "cerere.in"
#define FOUT "cerere.out"
#define NMAX 100001
#define INF 0x3f3f3f3f

int a[30][NMAX], K[NMAX], s[NMAX], str[NMAX], N;

void read ()
{
    int x, y;

    scanf ("%d", &N);
    memset (s, INF, sizeof (s));

    for (int i = 1; i <= N; ++ i)
    {
        scanf ("%d", &K[i]);
        if (!K[i])
            str[i] = s[i] = 0;
    }

    for (int i = 1; i < N; ++ i)
    {
        scanf ("%d%d", &x, &y);
        a[0][y] = x;
    }

    for (int k = 1; k <= 30; ++ k)
        for (int i = 1; i <= N; ++ i)
            a[k][i] = a[k-1][a[k-1][i]];
}

int search (int stramos, int nod)
{
    int nodc = nod;
    
    for (int i = 0; i <= 30; ++ i)
        if ((stramos & (1 << i)) != 0)
            nodc = a[i][nodc];

    return nodc;
}

int remake (int nod)
{
    if (s[nod] < INF)
        return s[nod];
    else
        return s[nod] = remake(str[nod]) + 1;
}

void solve ()
{
    for (int i = 1; i <= N; ++ i)
        if (K[i])
            str[i] = search (K[i], i);

    /*for (int i = 1; i <= N; ++ i)
        if (s[i] >= INF)
            remake (i);*/
    int ct;
    for (int i = 1; i <= N; ++ i)
        if (s[i])
        {
            ct = 0;
            int j = i;
            while (str[j])
            {
                j = str[j];
                ++ ct;
            }
           s[i] = ct + s[j];
        }

    for (int i = 1; i <= N; ++ i)
        printf ("%d ", s[i]);
    printf ("\n");
}

int
 main ()
{
    freopen (FIN, "rt", stdin);
    freopen (FOUT, "wt", stdout);

    read ();
    solve ();

    return 0;
}