Cod sursa(job #586206)

Utilizator freak93Adrian Budau freak93 Data 30 aprilie 2011 14:05:43
Problema Guvern Scor 100
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 1.64 kb
#include <fstream>
#include <set>
#include <vector>

using namespace std;

const char iname[] = "guvern.in";
const char oname[] = "guvern.out";
const int maxn = 200005;
const int inf = 1000000005;

ifstream f(iname);
ofstream g(oname);

set< pair<int, int> > S;
int v[maxn], been[maxn], start[maxn], end[maxn], k;
vector<int> E[maxn], Q[maxn];
int tmp[maxn], tmpbest[maxn], take[maxn];

void dfs(int x) {
	been[x] = 1;
	start[x] = k;
	S.insert(make_pair(v[x], x));
	
	for (vector<int>::iterator it = E[x].begin(); it != E[x].end(); ++it)
		if (been[*it] == 0)
			dfs(*it);
	end[x] = ++k;

	S.erase(make_pair(v[x], x));
	if (x != 0) {
		set< pair<int, int> >::iterator poz = S.lower_bound(make_pair(v[x], x));
		Q[poz -> second].push_back(x);
		//fprintf(stderr, "%d(%d) up %d(%d)\n", x, v[x], poz -> second, v[poz -> second]);
	}

	int p = 0;
	for (vector<int>::iterator it = Q[x].begin(); it != Q[x].end(); ++it) {
		tmp[++p] = *it;
		tmpbest[p] = take[*it];
		int aux = 0;

		while (p > 1 && start[tmp[p - 1]] >= start[tmp[p]] && end[tmp[p - 1]] <= end[tmp[p]]) {
			//fprintf(stderr, "%d(%d) intra in %d(%d)\n", tmp[p - 1], tmpbest[p - 1], tmp[p], tmpbest[p]);
			aux += tmpbest[p - 1];
			tmp[p - 1] = tmp[p];
			tmpbest[p - 1] = tmpbest[p];
			--p;
		}
		tmpbest[p] = max(tmpbest[p], aux);
	}

	//fprintf(stderr, "\n");

	while (p--) 
		take[x] += tmpbest[p + 1];
	++take[x];
	//fprintf(stderr, "%d -> %d\n", x, take[x]);
}


int main() {
	int N;
	f >> N;
	for (int i = 1; i < N; ++i) {
		int x, y;
		f >> x >> y;
		E[x].push_back(y);
		E[y].push_back(x);
	}
	
	for (int i = 1; i <= N; ++i)
		f >> v[i];

	v[0] = inf;
	E[0].push_back(1);
	dfs(0);

	g << take[0] - 1 << "\n";
}