#include #include #include #include using namespace std; struct vertices { std::vector neighbors_of(unsigned int v1) { return neighbors[v1 - 1]; } void add_neighbors(unsigned int v1, unsigned int v2) { neighbors[v1 - 1].push_back(v2); neighbors[v2 - 1].push_back(v1); } explicit vertices(unsigned int n) { neighbors = vector>(n); } private: vector> neighbors; }; struct path { unsigned int max_weight = 0; std::set vertices; }; struct paths_of_length { void add_path(unsigned int v1, unsigned int v2, const path& p) { if (v1 > v2) std::swap(v1, v2); if (paths.count({v1, v2})) return; paths[{v1, v2}] = p; } path& get_path(unsigned int v1, unsigned int v2) { if (v1 > v2) std::swap(v1, v2); return paths[{v1, v2}]; } // vertices + max weight vertex on path between them // vertices should be in ascending order std::map, path> paths; }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); unsigned int N; cin >> N; vertices g = vertices(N); std::vector weights(N); for (unsigned int i = 0; i < N; i++) { std::cin >> weights[i]; } // length = index + 1 std::vector dp; dp.emplace_back(); for (unsigned int i = 0; i < N - 1; i++){ unsigned int v1, v2; cin >> v1 >> v2; g.add_neighbors(v1, v2); dp[0].add_path(v1, v2, path{max(weights[v1 - 1], weights[v2 - 1]), {v1, v2}}); } unsigned long beauty = 0; for (unsigned long i = 0; i < dp.size(); i ++) { for (const auto& [whatever, path] : dp[i].paths) { beauty = (beauty + path.max_weight * (i + 1)) % 1000000007; } } bool added_new = true; unsigned int j = 1; while (added_new) { dp.emplace_back(); added_new = false; for (const auto& [key, path] : dp[j - 1].paths) { for (unsigned int next_vertex : g.neighbors_of( key.first)) { // add neighbor if it isn't in the path already if (!path.vertices.count(next_vertex)) { added_new = true; auto new_vertices = path.vertices; new_vertices.insert(next_vertex); dp[j].add_path(key.second, next_vertex, {max(weights[next_vertex - 1], path.max_weight), new_vertices}); } } for (unsigned int next_vertex : g.neighbors_of( key.second)) { if (!path.vertices.count(next_vertex)) { added_new = true; auto new_vertices = path.vertices; new_vertices.insert(next_vertex); dp[j].add_path(key.first, next_vertex, {max(weights[next_vertex - 1], path.max_weight), new_vertices}); } } } for (const auto& [whatever, path] : dp[j].paths) { beauty = (beauty + path.max_weight * (j + 1)) % 1000000007; } dp[j - 1] = paths_of_length(); j++; } std::cout << beauty << '\n'; return 0; }