Cod sursa(job #585680)

Utilizator savimSerban Andrei Stan savim Data 30 aprilie 2011 10:58:21
Problema Guvern Scor 0
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 1.35 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define MAX_N 200010

int n, m, sol, p2;

int use[MAX_N], cost[MAX_N], d[MAX_N], Q[MAX_N];

int tata[20][MAX_N];

vector <int> G[MAX_N];

inline int get_vertex(int nod, int val) {
	if (nod == 0)
		return 0;
	
	for (int i = p2; i >= 0; i--)
		if (cost[tata[i][nod]] > val)
			nod = tata[i][nod];

	return nod;
}

void dfs(int nod) {
	use[nod] = d[nod] = 1;
	                      
	Q[++m] = nod;
	int last = get_vertex(Q[m - 1], cost[nod]);

	if (last != 0 && cost[last] > cost[nod])
		tata[0][nod] = tata[0][last]; //practic nod il elimina pe last
	else
		tata[0][nod] = last;

	for (int i = 1; i < p2; i++)
		tata[i][nod] = tata[i - 1][tata[i - 1][nod]];

	for (vector <int>::iterator it = G[nod].begin(); it != G[nod].end(); ++it)
		if (use[*it] == 0)
			dfs(*it);

	if (last != 0 && cost[last] > cost[nod])
		d[last] += d[nod];

	Q[m--] = 0;

	sol = max(sol, d[nod]);
}

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

	scanf("%d", &n);
	for (int i = 1; i < n; i++) {
		int x, y;
		scanf("%d %d", &x, &y);

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

	for (int i = 0;; i++)
		if ((1 << i) >= n) {
        	p2 = i;
			break;
		}

	cost[0] = -2000000000;
	dfs(1);

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

	return 0;
}