Cod sursa(job #1165359)

Utilizator eudanipEugenie Daniel Posdarascu eudanip Data 2 aprilie 2014 17:29:00
Problema Guvern Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;

#define NMAX 200005
#define pi pair<int,int>
#define x first
#define y second
#define mp make_pair
#define pb push_back

int grad[NMAX],sfarsit[NMAX],trecut[NMAX];
int nrp,nr,d[NMAX],sol,n,smax,start[NMAX];
char boss[NMAX],viz[NMAX];

class cmp
{
public:
    bool operator()(const int& a, const int& b)
    {
        return grad[a] < grad[b];
    }
};

set<int,cmp> myset;
set<int,cmp> ::iterator it;
pi perechi[2 * NMAX];
vector<int> v[NMAX],go[NMAX];

inline int cmp2(const pi& a,const pi& b)
{
    int t1 = (a.y == 0 ? start[a.x] : sfarsit[a.x]);
    int t2 = (b.y == 0 ? start[b.x] : sfarsit[b.x]);
    if(t1 == t2)
        return a.y < b.y;
    return t1 < t2;
}

inline void dfs(int nod)
{
    it = myset.lower_bound(nod);
    if(it != myset.end())
    {
        int val = *it;
        go[val].pb(nod);
    }
    else
    {
 /*       int cnod = nod;
        while(tata[cnod])
        {
            if(grad[tata[cnod]] > grad[nod])
                printf("pllll\n");
            cnod = tata[cnod];
        }*/
        boss[nod] = 1;
    }
    viz[nod] = 1;

    myset.insert(nod);
    int i,vec,lim = v[nod].size();
    for(i = 0; i < lim; i++)
        if(!viz[vec = v[nod][i]])
        {
          //  tata[vec] = nod;
            dfs(vec);
        }
    myset.erase(nod);
}

inline void dfs2(int nod)
{
    int i,vec,lim = v[nod].size();
    pi p;

    viz[nod] = 1;
    start[nod] = ++nr;
    for(i = 0; i < lim; i++)
        if(!viz[vec = v[nod][i]])
            dfs2(vec);

    sfarsit[nod] = nr;

    lim = go[nod].size();
    nrp = 0;
    for(i = 0; i < lim; i++)
    {
        vec = go[nod][i];
        perechi[++nrp] = mp(vec,0);
        perechi[++nrp] = mp(vec,1);
    }
    sort(perechi + 1,perechi + nrp + 1,cmp2);
    smax = 1;
    for(i = 1; i <= nrp; i++)
    {
        p = perechi[i];
     //   printf("pereche %d %d %d %d\n",p.x,p.y,start[p.x],sfarsit[p.x]);
        if(!trecut[p.x])
            trecut[p.x] = smax;
        else
            smax = max(smax,trecut[p.x] + d[p.x]);
    }
    d[nod] = smax;
    if(boss[nod] == 1)
        sol = max(sol,d[nod]);
}

int main ()
{
    int i,a,b;

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

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

    dfs(1);
    memset(viz,0,sizeof(viz));
    dfs2(1);

    printf("%d\n",sol);

    return 0;
}