Cod sursa(job #585871)

Utilizator PavelRazvanPavel Razvan PavelRazvan Data 30 aprilie 2011 12:21:40
Problema Guvern Scor 0
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 2.33 kb
#include<algorithm>
#include<cstdio>
using namespace std;
#include<vector>
#include<queue>

#define DIM 200001
#define pb push_back

struct ok
{
    int x,y,t;
} c[DIM];
int n,rez,poz;
vector <int> lst[DIM],a,b;
queue <int> q,q2;

struct cmp1
{
    bool operator () (const ok &x,const ok &y) const
    {
        return x.x<y.x;
    }
};
struct cmp2
{
    bool operator () (const ok &x,const ok &y) const
    {
        return x.y<y.y;
    }
};

inline void read ()
{
    int i,nr1,nr2;

    scanf("%d",&n);
    for(i=1;i<n;++i)
    {
        scanf("%d%d",&nr1,&nr2);
        lst[nr1].pb(nr2);
        lst[nr2].pb(nr1);
    }
    for(i=1;i<=n;++i)
        scanf("%d",&c[i].x),c[i].y=i;
}

inline void norm ()
{
    int i;

    sort(1+c,1+c+n,cmp1 ());
    for(i=1;i<=n;++i)
        c[i].x=i;
    sort(1+c,1+c+n,cmp2 ());
}

inline int cbin (int x,int sol)
{
	int st=1,dr=sol,mij,rez2=0;
	while(st<=dr)
	{
		mij=(st+dr)/2;
		if(a[b[mij]]<x)
			rez2=mij,st=mij+1;
		else
			dr=mij-1;
	}
	return rez2;
}

inline int scmax ()
{
	int i,sol;
	b.clear ();
	for(i=0;i<=a.size ();++i)
        b.pb (0);
	b[1]=1;
	sol=1;
	for(i=2;i<a.size();++i)
	{
		poz=cbin(a[i],sol);
		b[poz+1]=i;
		if(poz+1>sol)
			++sol;
	}
	return sol;
}

inline void solve ()
{
    int i,nr;

    c[1].y=0;
    for(i=2;i<=n;++i)
        if(lst[i].size ()==1)
        {
            q.push (i);
            q2.push (i);
            c[i].y=1;
        }
        else
            c[i].y=0;

    while(!q.empty ())
    {
        nr=q.front ();
        for(i=0;i<lst[nr].size ();++i)
        {
            ++c[lst[nr][i]].y;
            if(c[lst[nr][i]].y<=lst[lst[nr][i]].size ()-1 || lst[nr][i]==1)
                c[nr].t=lst[nr][i];
            if(c[lst[nr][i]].y==lst[lst[nr][i]].size ()-1)
                q.push (lst[nr][i]);
        }
        q.pop ();
    }
    for(i=1;i<=n;++i)
        lst[i].clear ();
    while(!q2.empty ())
    {
        nr=q2.front ();
        a.clear ();
        a.pb(0);
        for(i=nr;i;i=c[i].t)
            a.pb(c[i].x);
        rez=max(rez,scmax ());
        q2.pop ();
    }
}

int main ()
{
    freopen("guvern.in","r",stdin);
    freopen("guvern.out","w",stdout);
    read ();
    norm ();
    solve ();
    printf("%d\n",rez);
    return 0;
}