Cod sursa(job #584399)

Utilizator andrei.12Andrei Parvu andrei.12 Data 25 aprilie 2011 12:45:44
Problema Guvern Scor Ascuns
Compilator cpp Status done
Runda Marime 1.87 kb
#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>

using namespace std;

const int MAXN = 200010;
const int INF = 2000000000;
const int MAXV = 1000000000;

int n;
vector <int> tree[MAXN];
int values[MAXN];
char visited[MAXN];
set < pair <int, int> > stack;
vector <int> events[MAXN];
vector <int> lookup[MAXN];
int maxSetSize[MAXN], dp[MAXN];

void DFS(int vertex) {
	visited[vertex] = 1;

	set < pair <int, int> > :: iterator it = stack.upper_bound(make_pair(values[vertex], 0));
	int parent = it -> second;
	int localLookup = events[parent].size();
	stack.insert(make_pair(values[vertex], vertex));

	//printf("%d %d\n", vertex, parent);

	for (size_t i = 0; i < tree[vertex].size(); ++i)
		if (!visited[tree[vertex][i]])
			DFS(tree[vertex][i]);

	dp[0] = 1;
	for (size_t i = 0; i < events[vertex].size(); ++i) 
		dp[i+1] = max(dp[i], dp[lookup[vertex][i]] + maxSetSize[events[vertex][i]]);
	maxSetSize[vertex] = dp[events[vertex].size()];

	stack.erase(make_pair(values[vertex], vertex));
	events[parent].push_back(vertex);
	lookup[parent].push_back(localLookup);
}

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

	scanf("%d ", &n);
	assert(1 <= n && n <= 200000);

	for (int i = 1; i < n; ++i) {
		int x, y;
		scanf("%d %d", &x, &y);
		assert(1 <= x && x <= n);
		assert(1 <= y && y <= n);
		tree[x].push_back(y);
		tree[y].push_back(x);
	}

	for (int i = 1; i <= n; ++i) {
		scanf("%d ", &values[i]);
		assert(-MAXV <= values[i] && values[i] <= MAXV);
	}

	int tmpValues[MAXN];
	for (int i = 1; i <= n; ++i)
		tmpValues[i] = values[i];

	sort(tmpValues+1, tmpValues+n+1);
	for (int i = 2; i <= n; ++i)
		assert(tmpValues[i-1] < tmpValues[i]);

	values[0] = INF;
	tree[0].push_back(1);
	tree[1].push_back(0);

	DFS(0);

	for (int i = 1; i <= n; ++i)
		assert(visited[i] == 1);

	printf("%d\n", maxSetSize[0]-1);

	return 0;
}