Cod sursa(job #1086970)

Utilizator valentin.harsanValentin Harsan valentin.harsan Data 18 ianuarie 2014 19:08:40
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.92 kb
#include<iostream>
#include<fstream>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;

const int N = 210000;

int n, c[N], nrr[N], cs[N], cd[N], nu;
bool ver[N];
vector<int> v[N], g[N];
set<pair<int, int> > s;

void df(int nod, int p) {
    set<pair<int, int> >::iterator itt = s.upper_bound(pair<int, int>(c[nod], 0));

    if(itt != s.end())
        g[itt->second].push_back(nod);

    s.insert(pair<int, int>(c[nod], nod));

    cs[nod] = ++nu;

    for(vector<int>::iterator it = v[nod].begin(); it != v[nod].end(); ++it) if(*it != p)
        df(*it, nod);

    s.erase(s.find(pair<int, int>(c[nod], nod)));

    cd[nod] = nu;
}

bool cmp(int a, int b) {
    return cs[a] < cs[b];
}

int calc(int nod, int l, int r) {
    int i, pas = 1<<19;
    if(l > r)
        return 0;

    for(i = l; pas; pas >>= 1) {
        if(i + pas <= r && cd[g[nod][l]] >= cs[g[nod][i + pas]])
            i += pas;
    }

    return max(nrr[g[nod][l]], calc(nod, l + 1, i)) + calc(nod, i + 1, r);
}

void df2(int nod, int start) {
    ver[nod] = 1;

    sort(g[nod].begin(), g[nod].end(), cmp);

    for(vector<int>::iterator it = g[nod].begin(); it != g[nod].end(); ++it) if(!ver[*it])
        df2(*it, start);

    nrr[nod] = 1 + calc(nod, 0, g[nod].size() - 1);
}

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

    cin >> n;

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

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

    df(0, -1);

    for(i = 0; i <= n; ++i) if(!ver[i])
        df2(i, i);

    cout << nrr[0] - 1;

    return 0;
}