Cod sursa(job #586707)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 2 mai 2011 20:02:00
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.52 kb
#include <stdio.h>
#include <vector>
#include <set>

using namespace std;

#define maxn 200010

int n, i, j, k, a, b, el, poz, rez, coop[maxn], f[maxn], d[maxn], sv[maxn], dsv[maxn];
vector<int> v[maxn], prov[maxn];
set<pair<int, int> > g;
int st[maxn], dr[maxn];

int verif(int nc, int nod)
{
    return (st[nod]<=st[nc] && dr[nc]<=dr[nod]);
}

void df(int nod, int tata)
{
    if(f[nod]==1)
        return;
    f[nod]=1;

    g.insert(make_pair(coop[nod], nod));

    st[nod]=++poz;
    for(int i=0; i<v[nod].size(); ++i)
        if(f[v[nod][i]]==0)
            df(v[nod][i], nod);
    dr[nod]=++poz;

    g.erase(make_pair(coop[nod], nod));

    set<pair<int, int> > ::iterator it=g.lower_bound(make_pair(coop[nod], 0));
    if(it!=g.end())
        prov[it->second].push_back(nod);

    sv[0]=0;
    int sum=0;

    for(int i=0; i<prov[nod].size(); ++i)
    {
        sum=0;

        while(sv[0]>0 && verif(sv[sv[0]], prov[nod][i]))
            sum+=dsv[sv[0]--];

        sv[++sv[0]]=prov[nod][i];
        dsv[sv[0]]=max(d[prov[nod][i]], sum);
    }

    for(int i=1; i<=sv[0]; ++i)
        d[nod]+=dsv[i];
    ++d[nod];

    rez=max(rez, d[nod]);
}

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

    scanf("%d", &n);
    for(int i=1; i<n; ++i)
    {
        scanf("%d%d", &a, &b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    for(int i=1; i<=n; ++i)
        scanf("%d", &coop[i]);

    v[0].push_back(1);
    coop[0]=2000000000;

    df(0, 0);

    printf("%d\n", rez-1);
    return 0;
}