Cod sursa(job #2458197)

Utilizator Andrei_CotorAndrei Cotor Andrei_Cotor Data 19 septembrie 2019 20:33:58
Problema Guvern Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.67 kb
#include<fstream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;

ifstream fi("guvern.in");
ofstream fo("guvern.out");

int Coop[200005],Dp[200005],nr,Sum[200005];
vector<int> A[200005];
vector<int> Sclav[200005]; //aka Impact, no offence Sarb
set<pair<int,int> > S;
pair<pair<int,int>,int> Segm[200005];
int St[200005];
int Dr[200005];

bool cmp(pair<pair<int,int>,int> a, pair<pair<int,int>,int> b)
{
    return a.first.second<b.first.second;
}

int src(int val, int n)
{
    int rez=0;
    for(int i=17; i>=0; i--)
        if(rez+(1<<i)<=n && Segm[rez+(1<<i)].first.second<val)
            rez+=(1<<i);
    return rez;
}

int dp(int nod)
{
    int nrs=0;
    for(vector<int>::iterator it=Sclav[nod].begin(); it!=Sclav[nod].end(); it++)
        Segm[++nrs]={{St[*it],Dr[*it]},Dp[*it]};

    sort(Segm+1,Segm+nrs+1,cmp);

    for(int i=1; i<=nrs; i++)
        Sum[i]=max(Sum[i-1],Sum[src(Segm[i].first.first,nrs)]+Segm[i].second);
    return Sum[nrs];
}

void dfs(int nod, int p)
{
    int coresp=(*S.lower_bound({Coop[nod],0})).second;
    Sclav[coresp].push_back(nod);

    S.insert({Coop[nod],nod});
    St[nod]=++nr;

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

    S.erase({Coop[nod],nod});
    Dr[nod]=++nr;
    Dp[nod]=1+dp(nod);
}

int main()
{
    int n;
    fi>>n;
	for(int i=1; i<n; i++)
	{
        int x,y;
        fi>>x>>y;
        A[x].push_back(y);
        A[y].push_back(x);
	}
	for(int i=1; i<=n; i++)
        fi>>Coop[i];

    nr=0;
    dfs(1,0);

    int rez=dp(0);
    for(int i=1; i<=n; i++)
        rez=max(rez,Dp[i]);
    fo<<rez<<"\n";
    fi.close();
    fo.close();
    return 0;

}