Cod sursa(job #1758613)

Utilizator akaprosAna Kapros akapros Data 17 septembrie 2016 15:41:44
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include <bits/stdc++.h>
#define maxN 200002
#define pb push_back
#define pii pair < int, int >
#define mp make_pair
#define f first
#define s second
#define inf 1000000000
using namespace std;
int n, m, ans, dg[maxN], l[maxN], r[maxN], pe;
int st[maxN], dp[maxN], d[maxN];
vector < int > V[maxN];
set < pii > S;
vector < int > mand[maxN];
bool vis[maxN];
void read()
{
    freopen("guvern.in", "r", stdin);
    scanf("%d", &n);
    for (int i = 1; i < n; ++ i)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        V[x].pb(y);
        V[y].pb(x);
    }
    for (int i = 1; i <= n; ++ i)
        scanf("%d", &dg[i]);
    V[0].pb(1);
    dg[0] = inf;
}
int ok(int x, int y)
{
    return (l[x] >= l[y] && r[x] <= r[y]);
}
void dfs(int x)
{
    int i, node, len = V[x].size();
    vis[x] = 1;
    S.insert(mp(dg[x], x));
    l[x] = ++ pe;
    for (i = 0; i < len; ++ i)
        if (!vis[node = V[x][i]])
        {
            dfs(node);

        }
    r[x] = ++ pe;
    S.erase(mp(dg[x], x));
    set < pii > :: iterator it = S.lower_bound(mp(dg[x], 0));
    if (it != S.end())
        mand[it->s].pb(x);
    len = mand[x].size();
    int top = 0, sum = 0;
    dp[x] = 1;
    for (i = 0; i < len; ++ i)
    {
        sum = 0;
        node = mand[x][i];
        while (top && ok(st[top], node))
        {
            sum += d[top];
            -- top;
        }
        st[++ top] = node;
        d[top] = max(sum, dp[node]);
    }

    while (top)
        dp[x] += d[top --];
    if (dp[x] > ans)
        ans = dp[x];
}
void solve()
{
    dfs(0);
}
void write()
{
    freopen("guvern.out", "w", stdout);
    printf("%d\n", -- ans);
}
int main()
{
    read();
    solve();
    write();
    return 0;
}