Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define gcd __gcd
- #define bitcount __builtin_popcountll
- #define rep(i,j,n) for(i=j;i<n;i++)
- #define tr(it,c) for(auto it=(c).begin();it!=(c).end();it++)
- #define pb push_back
- #define mp make_pair
- #define hell 1000000007
- #define uset unordered_set
- #define umap unordered_map
- #define ft first
- #define sc second
- using namespace std;
- typedef long long ll;
- typedef pair<ll,ll> pl;
- template <class T> T& get(T &n) {
- cin>>n;
- return n;
- }
- struct edge{
- int n[2];
- inline int& operator[](int i){
- assert(i==0 || i==1);
- return n[i];
- }
- };
- struct Tree{
- int N;
- vector<ll> a;
- vector<edge> e;
- vector<vector<int>> adj;
- vector<vector<pl>> dp;
- vector<vector<ll>> dp2;
- Tree(int N):N(N),a(N),e(N-1),adj(N),dp(N-1,vector<pl>(2,mp(-1LL,-1LL))),dp2(N-1,vector<ll>(2,-1LL)){
- }
- ll solve(int i,int idx){ // returns best but computes both best and second best
- int u=e[i][idx];
- auto ref=&dp[i][idx];
- if(*ref==mp(-1LL,-1LL)){
- priority_queue<ll,vector<ll>,greater<ll>> q;
- for(auto j:adj[u]){
- if(i==j) continue;
- int v=e[j][0]^e[j][1]^u;
- ll p=solve(j,(e[j][0]==v?0:1));
- q.push(p);
- if(q.size()>2) q.pop();
- }
- q.push(0);q.push(0);
- while(q.size()>2) q.pop();
- ref->sc=q.top()+a[u];q.pop();
- ref->ft=q.top()+a[u];q.pop();
- }
- return ref->ft;
- }
- ll solve2(int i,int idx){
- int u=e[i][idx];
- auto ref=&dp2[i][idx];
- if(*ref==-1LL){
- ll ans=dp[i][idx].ft+dp[i][idx].sc-a[u];
- for(auto j:adj[u]){
- if(i==j) continue;
- int v=e[j][0]^e[j][1]^u;
- ll p=solve2(j,(e[j][0]==v?0:1));
- ans=max(p,ans);
- }
- *ref=ans;
- }
- return *ref;
- }
- ll solve3(){
- ll ans=0;
- for(int i=0;i<N-1;i++){
- ans=max(ans,dp2[i][0]+dp2[i][1]);
- }
- return ans;
- }
- };
- int main() {
- int N,i;
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- cin>>N;
- Tree t(N);
- rep(i,0,N){
- get(t.a[i]);
- }
- rep(i,0,N-1){
- int u=--get(t.e[i][0]);
- int v=--get(t.e[i][1]);
- t.adj[u].push_back(i);
- t.adj[v].push_back(i);
- }
- rep(i,0,N-1){
- t.solve(i,0);
- t.solve(i,1);
- }
- rep(i,0,N-1){
- t.solve2(i,0);
- t.solve2(i,1);
- }
- cout<<t.solve3()<<endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement