Cod sursa(job #1592688)

Utilizator dm1sevenDan Marius dm1seven Data 7 februarie 2016 20:48:45
Problema Asmax Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <utility>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include <stack>
#include <fstream>
#include <chrono>
using namespace std;
using namespace std::chrono;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<ull> vull;
typedef vector<vull> vvull;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;

#define fs first
#define sc second
#define pb push_back
// forward strict for, most common
#define fors(i, a, n) for (int i = (int) (a); i < (int) (n); ++i)
// forward inclusive for
#define fori(i, a, n) for (int i = (int) (a); i <= (int) (n); ++i)
// backward for, inclusive
#define forb(i, n, a) for (int i = (int) n; i >= a; --i)

class Problem {
public:
    int n;
    vint sm;
    vint a;
    vvint adj;
    vint dp;
    int lmin = numeric_limits<int>::min();

    void solve() {
        ifstream in("asmax.in");
        ofstream out("asmax.out");

        int n;
        in >> n;
        sm = vint(n + 1, lmin);
        dp = vint(n + 1, lmin);
        a = vint(n + 1);

        fori(i, 1, n)
            in >> a[i];
        adj = vvint(n + 1);
        fors(i, 1, n)
        {
            int u, v;
            in >> u >> v;
            adj[u].push_back(v);
            adj[v].push_back(u);
        }

        sm[1] = fdp(1);
        transfer_root(1);

        int smax = lmin;
        fori(i, 1, n) smax = max(smax, sm[i]);
        
        out << smax << endl;
        
        // try all roots
//        int smax = lmin;
//        fori(i, 1, n)
//        {
//            dp = vint(n + 1, lmin);
//            sm[i] = fdp(i);
//            smax = max(smax, sm[i]);
//        }
    }

    void transfer_root(int u) {
        for (int v : adj[u]) {
            if (sm[v] == lmin) {
                int dp1u = dp[u], dp1v = dp[v]; // save the original state
                // the new state
                int dp2u = dp[u];
                if (dp[v] >= 0) dp2u = dp[u] - dp[v];
                int dp2v = dp[v];
                if (dp2u >= 0) dp2v += dp2u;

                sm[v] = dp2v; // save the maximum of the subtree with v as root

                // store the new state and call recursively
                dp[u] = dp2u;
                dp[v] = dp2u;

                transfer_root(v);
                
                // restore the original state
                dp[u] = dp1u;
                dp[v] = dp1v;
            }
        }
    }

    int fdp(int u) {
        if (dp[u] != lmin) return dp[u];
        dp[u] = a[u];
        for (int v : adj[u]) {
            if (dp[v] != lmin) continue;
            int dpv = fdp(v);
            if (dpv >= 0) dp[u] += dpv;
        }

        return dp[u];
    }
};

int main() {
    Problem p;
    p.solve();

    return 0;
}