Cod sursa(job #2247099)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 27 septembrie 2018 21:34:57
Problema Guvern Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = (int) 2e5;

vector <int> g[MAXN + 1];
int vals[MAXN + 1];

vector <int> nodes[MAXN + 1];

struct Data {
    int nod;
    bool operator <(const Data &other) const {
        return vals[nod] < vals[other.nod];
    }
};

set <Data> mst;

pair <int, int> id[MAXN + 1];
int cnt;

void dfs(int nod, int par) {
    id[nod].first = ++cnt;
    auto it = mst.upper_bound({nod});
    if(it != mst.end()) {
        nodes[it -> nod].push_back(nod);
    }
    else {
        nodes[0].push_back(nod);
    }
    mst.insert({nod});
    for(auto it : g[nod]) {
        if(it != par) {
            dfs(it, nod);
        }
    }
    mst.erase(mst.find({nod}));
    id[nod].second = cnt;
}

bool cmp(int a, int b) {
    if(id[a].first == id[b].first)
        return id[a].second < id[b].second;
    return id[a].first < id[b].first;
}

int dp[MAXN + 1];

void dfs1(int nod, int par) {
    for(auto it : g[nod]) {
        if(it != par) {
            dfs1(it, nod);
        }
    }
    sort(nodes[nod].begin(), nodes[nod].end(), cmp);
    int pos = 0, sz = nodes[nod].size();
    vector <int> best;
    best.resize(sz);
    dp[nod] = 1;
    for(int i = 0; i < sz; i++) {
        while(pos < sz && id[nodes[nod][pos]].second < id[nodes[nod][i]].first) {
            pos++;
        }
        if(i > 0) {
            if(pos > 0) {
                best[i] = max(best[i - 1], dp[nodes[nod][i]] + best[pos - 1]);
            }
            else {
                best[i] = best[i - 1];
            }
        }
        else {
            best[i] = dp[nodes[nod][i]];
        }
    }
    if(best.size()) {
        dp[nod] += best.back();
    }
}

int main() {
    FILE *fi, *fout;
    int i, n;
    fi = fopen("guvern.in" ,"r");
    fout = fopen("guvern.out" ,"w");
    fscanf(fi,"%d " ,&n);
    for(i = 1; i < n; i++) {
        int x, y;
        fscanf(fi,"%d %d " ,&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i = 1; i <= n; i++) {
        fscanf(fi,"%d " ,&vals[i]);
    }
    dfs(1, 0);
    g[0].push_back(1);
    dfs1(0, 0);
    dp[0]--;
    int ans = 0;
    for(i = 0; i <= n; i++) {
        ans = max(ans, dp[i]);
    }
    fprintf(fout,"%d" ,ans);
    fclose(fi);
    fclose(fout);
    return 0;
}