Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cmath>
- #include <cstdlib>
- #include <cassert>
- #include <ctime>
- #include <cstring>
- #include <string>
- #include <set>
- #include <map>
- #include <vector>
- #include <list>
- #include <deque>
- #include <queue>
- #include <sstream>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define pb push_back
- #define mp make_pair
- #define fs first
- #define sc second
- const double pi = acos(-1.0);
- const int size = 1000 * 1000 + 100;
- int n;
- long long a[size];
- long long insubtree[size];
- long long longest[size];
- long long ans = 0;
- vector <int> vertex[size];
- void dfs1(int v, int f) {
- vector <long long> mxs;
- longest[v] = a[v];
- insubtree[v] = a[v];
- for (int i = 0; i < (int) vertex[v].size(); i++) {
- if (vertex[v][i] != f) {
- dfs1(vertex[v][i], v);
- longest[v] = max(longest[v], longest[vertex[v][i]] + a[v]);
- insubtree[v] = max(insubtree[v], insubtree[vertex[v][i]]);
- mxs.pb(longest[vertex[v][i]]);
- }
- }
- sort(mxs.rbegin(), mxs.rend());
- if ((int) mxs.size() > 0) {
- insubtree[v] = max(insubtree[v], mxs[0] + a[v]);
- }
- if ((int) mxs.size() > 1) {
- insubtree[v] = max(insubtree[v], mxs[0] + mxs[1] + a[v]);
- }
- }
- void dfs2(int v, int f, long long best, long long lgt) {
- ans = max(ans, insubtree[v] + best);
- set <pair <long long, int> > bestset;
- set <pair <long long, int> > lgtset;
- bestset.insert(mp(best, -1));
- lgtset.insert(mp(lgt, -1));
- for (int i = 0; i < (int) vertex[v].size(); i++) {
- if (vertex[v][i] != f) {
- bestset.insert(mp(insubtree[vertex[v][i]], i));
- lgtset.insert(mp(longest[vertex[v][i]], i));
- }
- }
- for (int i = 0; i < (int) vertex[v].size(); i++) {
- if (vertex[v][i] != f) {
- bestset.erase(mp(insubtree[vertex[v][i]], i));
- lgtset.erase(mp(longest[vertex[v][i]], i));
- long long nb = bestset.rbegin()->fs;
- long long curb = a[v];
- set <pair <long long, int> >::iterator it = lgtset.end();
- if (lgtset.size() > 0) {
- --it;
- curb += it->fs;
- }
- if (lgtset.size() > 1) {
- --it;
- curb += it->fs;
- }
- dfs2(vertex[v][i], v, max(nb, curb), lgtset.rbegin()->fs + a[v]);
- bestset.insert(mp(insubtree[vertex[v][i]], i));
- lgtset.insert(mp(longest[vertex[v][i]], i));
- }
- }
- }
- int main() {
- scanf("%d", &n);
- for (int i = 0; i < n; i++)
- scanf("%lld", &a[i]);
- for (int i = 0; i < n - 1; i++) {
- int v, u;
- scanf("%d%d", &u, &v);
- u--, v--;
- vertex[v].pb(u);
- vertex[u].pb(v);
- }
- dfs1(0, -1);
- ans = 0ll;
- dfs2(0, -1, 0ll, 0ll);
- printf("%lld\n", ans);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment