Pagini recente » Cod sursa (job #2654823) | Cod sursa (job #3284251) | Autumn Warm Up 2007 | infoarena - comunitate informatica, concursuri de programare | Cod sursa (job #598267)
Cod sursa(job #598267)
#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;
}