/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 5ms 5.02 MiB
#2 Accepted 36ms 5.195 MiB
#3 Accepted 35ms 5.191 MiB
#4 Accepted 11ms 5.77 MiB
#5 Accepted 37ms 5.02 MiB
#6 Accepted 271ms 6.949 MiB
#7 Accepted 246ms 6.977 MiB
#8 Accepted 271ms 6.934 MiB
#9 Accepted 277ms 10.367 MiB
#10 Accepted 127ms 26.363 MiB
#11 Accepted 128ms 26.363 MiB
#12 Accepted 224ms 26.719 MiB
#13 Accepted 152ms 19.867 MiB
#14 Accepted 465ms 41.16 MiB
#15 Accepted 463ms 37.898 MiB
#16 Accepted 165ms 6.664 MiB

Code

//gpt
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXN = 200000 + 5;
const int H = 18;  // log2(MAXN) ≲ 18

int N;
vector<pair<int,int>> g[MAXN];
ll W[MAXN];

// — your centroid template arrays —
int sub[MAXN], cth[MAXN], ctp[MAXN];
int dist_arr[MAXN][H+1];

/// 1) compute subtree sizes on active nodes (cth[v]==0)
void dfs_siz(int u, int f){
    sub[u] = 1;
    for (auto &e : g[u]) {
        int v = e.first;
        if (v==f || cth[v]!=0) continue;
        dfs_siz(v, u);
        sub[u] += sub[v];
    }
}

/// 2) find the centroid of a component
int fc(int u, int f, int lim){
    for (auto &e : g[u]) {
        int v = e.first;
        if (v==f || cth[v]!=0) continue;
        if (sub[v] > lim)
            return fc(v, u, lim);
    }
    return u;
}

/// 3) (unused) fill dist_arr[u][h]
void dfs_dist(int u, int f, int d, int h){
    dist_arr[u][h] = d;
    for (auto &e : g[u]) {
        int v = e.first;
        if (v==f || cth[v]!=0) continue;
        dfs_dist(v, u, d+1, h);
    }
}

/// We'll collect (value, depth) pairs from each subtree:
///  value = sum W[...] - 2*sum C[...] along path from centroid's child
///  depth = the number of edges from centroid
void dfs_collect(int u, int f, ll curr, int depth,
                 vector<pair<ll,int>>& vals)
{
    vals.emplace_back(curr, depth);
    for (auto &e : g[u]) {
        int v = e.first, c = e.second;
        if (v==f || cth[v]!=0) continue;
        dfs_collect(v, u,
                    curr + W[v] - 2LL*c,
                    depth+1,
                    vals);
    }
}

ll answer;

/// 4) the modified decompose() that updates `answer`
void decompose(int entry, int parent=0, int height=1){
    // a) find centroid
    dfs_siz(entry, 0);
    int cent = fc(entry, 0, sub[entry]>>1);

    // b) (opt) compute dist_arr for this level
    dfs_dist(cent, 0, 0, height);

    // c) for all paths that pass through `cent`:
    //    we need two kinds:
    //      1) centroid-to-node at distance>=2
    //      2) node-in-subtree1 -> centroid -> node-in-subtree2
    ll bestVal = LLONG_MIN;

    for (auto &e : g[cent]) {
        int v = e.first, c = e.second;
        if (cth[v]!=0) continue;

        vector<pair<ll,int>> vals;
        // start from the child edge (cent->v):
        dfs_collect(v, cent,
                    W[v] - 2LL*c,
                    1,               // depth=1 for v
                    vals);

        // 1) centroid-to-node: only valid if depth>=2 (so cent and node not adjacent)
        for (auto &pr : vals) {
            ll d = pr.first;
            int depth = pr.second;
            if (depth >= 2) {
                answer = max(answer, d + W[cent]);
            }
        }

        // 2) cross-subtree pairing
        for (auto &pr : vals) {
            ll d = pr.first;
            if (bestVal != LLONG_MIN) {
                answer = max(answer, bestVal + d + W[cent]);
            }
        }
        // absorb this subtree's endpoint‐values
        for (auto &pr : vals) {
            bestVal = max(bestVal, pr.first);
        }
    }

    // d) finalize centroid
    cth[cent] = height;
    ctp[cent] = parent;

    // e) recurse on each remaining component
    for (auto &e : g[cent]) {
        int v = e.first;
        if (cth[v]==0)
            decompose(v, cent, height+1);
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T; 
    cin >> T;
    while (T--) {
        cin >> N;
        for (int i = 1; i <= N; i++) {
            cin >> W[i];
            g[i].clear();
            cth[i] = 0;
        }
        for (int i = 0; i < N-1; i++){
            int u,v,c;
            cin >> u >> v >> c;
            g[u].emplace_back(v,c);
            g[v].emplace_back(u,c);
        }

        answer = LLONG_MIN;
        decompose(1, 0, 1);
        cout << answer << "\n";
    }
    return 0;
}

Information

Submit By
Type
Submission
Problem
P1205 E. Make Cycle in Tree
Language
C++17 (G++ 13.2.0)
Submit At
2025-07-26 14:35:42
Judged At
2025-07-26 14:35:42
Judged By
Score
100
Total Time
465ms
Peak Memory
41.16 MiB