#include #include #include struct Vertex { int weight; std::vector children; }; typedef std::vector Graph; typedef std::vector Sum; Graph ReadTree() { int vertices_count; std::cin >> vertices_count; Graph tree(vertices_count); for (int i = 0; i < vertices_count; ++i) std::cin >> tree[i].weight; for (int i = 1; i < vertices_count; ++i) { int from, to, weight; std::cin >> from >> to; tree[from - 1].children.push_back(to - 1); tree[to - 1].children.push_back(from - 1); } return tree; } int dfs(const Graph &tree, int vertex, int parent, std::vector &w) { if ( w[vertex] == -1) { if (tree[vertex].children.size() == 0) { w[vertex] = tree[vertex].weight; } else { int m0 = tree[vertex].weight; for (int child : tree[vertex].children) { if (child != parent) { for (int gchild : tree[child].children) { if (gchild != child && gchild != vertex) { m0 += dfs(tree, gchild, child, w); } } } } int m1 = 0; for (int child : tree[vertex].children) { if (child != parent) { m1 += dfs(tree, child, vertex, w); } } w[vertex] = std::max(m0, m1); } } return w[vertex]; } int MaxWeightIndependentTreeSubset(const Graph &tree) { size_t size = tree.size(); if (size == 0) return 0; std::vector w(size, -1); return dfs(tree, 0, -1, w); } int main() { // This code is here to increase the stack size to avoid stack overflow // in depth-first search. const rlim_t kStackSize = 64L * 1024L * 1024L; // min stack size = 64 Mb struct rlimit rl; int result; result = getrlimit(RLIMIT_STACK, &rl); if (result == 0) { if (rl.rlim_cur < kStackSize) { rl.rlim_cur = kStackSize; result = setrlimit(RLIMIT_STACK, &rl); if (result != 0) { fprintf(stderr, "setrlimit returned result = %d\n", result); } } } // Here begins the solution Graph tree = ReadTree(); int weight = MaxWeightIndependentTreeSubset(tree); std::cout << weight << std::endl; return 0; }