253412026-02-19 11:40:14KevinRaktárba szállítás (45 pont)cpp17Elfogadva 45/4523ms2720 KiB
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int MAXN = 20005;

int N, K, C;
int parent_tree[MAXN];
int A[MAXN];
vector<int> adj[MAXN];

// Az Euler bejáráshoz (fa lapítása tömbbé)
int timer_dfs = 0;
int in_time[MAXN];
int out_time[MAXN];
int rev_in[MAXN];
int path_sum[MAXN];

// Szegmensfa tömbjei (méretük 4 * MAXN)
int tree_max[4 * MAXN];
int tree_idx[4 * MAXN];
int lazy_mod[4 * MAXN];

// DSU (Unió-Holkeresés) az üres városok gyors átugrásához
int parent_dsu[MAXN];

// DSU find fv: Megkeresi a legközelebbi ős-várost, ahol még van alkatrész
int find_anc(int u) {
    if (u == 0) return 0;
    if (parent_dsu[u] == u) return u;
    return parent_dsu[u] = find_anc(parent_dsu[u]);
}

// Szegmensfa felépítése
void build_seg(int node, int l, int r) {
    if (l == r) {
        tree_max[node] = path_sum[rev_in[l]];
        tree_idx[node] = rev_in[l];
        return;
    }
    int mid = l + (r - l) / 2;
    build_seg(2 * node, l, mid);
    build_seg(2 * node + 1, mid + 1, r);
    if (tree_max[2 * node] >= tree_max[2 * node + 1]) {
        tree_max[node] = tree_max[2 * node];
        tree_idx[node] = tree_idx[2 * node];
    } else {
        tree_max[node] = tree_max[2 * node + 1];
        tree_idx[node] = tree_idx[2 * node + 1];
    }
}

// Lazy propagation (lusta frissítés) továbbítása a gyermekek felé
void push_down(int node) {
    if (lazy_mod[node] != 0) {
        lazy_mod[2 * node] += lazy_mod[node];
        tree_max[2 * node] += lazy_mod[node];
        
        lazy_mod[2 * node + 1] += lazy_mod[node];
        tree_max[2 * node + 1] += lazy_mod[node];
        
        lazy_mod[node] = 0;
    }
}

// Szegmensfa frissítése (egy ág kapacitásának csökkentése)
void update_seg(int node, int l, int r, int ql, int qr, int val) {
    if (ql > r || qr < l) return;
    if (ql <= l && r <= qr) {
        tree_max[node] += val;
        lazy_mod[node] += val;
        return;
    }
    push_down(node);
    int mid = l + (r - l) / 2;
    update_seg(2 * node, l, mid, ql, qr, val);
    update_seg(2 * node + 1, mid + 1, r, ql, qr, val);
    
    if (tree_max[2 * node] >= tree_max[2 * node + 1]) {
        tree_max[node] = tree_max[2 * node];
        tree_idx[node] = tree_idx[2 * node];
    } else {
        tree_max[node] = tree_max[2 * node + 1];
        tree_idx[node] = tree_idx[2 * node + 1];
    }
}

int main() {
    // I/O műveletek felgyorsítása
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    if (!(cin >> N >> K >> C)) return 0;

    for (int i = 1; i <= N; ++i) {
        cin >> parent_tree[i] >> A[i];
        if (parent_tree[i] != 0) {
            adj[parent_tree[i]].push_back(i);
        }
    }

    // Iteratív DFS a memóriakorlát (Stack overflow) elkerülésére 
    vector<pair<int, int>> stk;
    stk.push_back({1, 0});
    path_sum[1] = A[1];
    in_time[1] = ++timer_dfs;
    rev_in[timer_dfs] = 1;

    while (!stk.empty()) {
        int u = stk.back().first;
        int &idx = stk.back().second;

        if (idx < adj[u].size()) {
            int v = adj[u][idx++];
            path_sum[v] = path_sum[u] + A[v];
            in_time[v] = ++timer_dfs;
            rev_in[timer_dfs] = v;
            stk.push_back({v, 0});
        } else {
            out_time[u] = timer_dfs;
            stk.pop_back();
        }
    }

    // Felépítjük a szegmensfát az 1..N intervallumra
    build_seg(1, 1, N);

    // DSU inicializálása
    parent_dsu[0] = 0; // A 0 az érvénytelen (raktár feletti) tartomány
    for (int i = 1; i <= N; ++i) {
        if (A[i] > 0) {
            parent_dsu[i] = i;
        } else {
            parent_dsu[i] = parent_tree[i];
        }
    }

    long long total_collected = 0;

    for (int k = 0; k < K; ++k) {
        int max_val = tree_max[1];
        int start_node = tree_idx[1];
        
        if (max_val <= 0) break; // Kifogytunk az alkatrészekből az egész hálózaton
        
        int need = C;
        int curr = find_anc(start_node);
        
        while (curr != 0 && need > 0) {
            int take = min(need, A[curr]);
            A[curr] -= take;
            need -= take;
            total_collected += take;
            
            // Csökkentjük a kiválasztott csomópont és minden alatta lévő csomópont útjának értékét
            update_seg(1, 1, N, in_time[curr], out_time[curr], -take);
            
            if (A[curr] == 0) {
                // Ha kiürült, kirekesztjük a DSU-ból (rámutatunk a szülőjére)
                parent_dsu[curr] = parent_tree[curr];
            }
            
            // Ugrás a következő olyan városra, ahol még van felvehető alkatrész
            curr = find_anc(parent_tree[curr]);
        }
    }

    cout << total_collected << "\n";

    return 0;
}
RészfeladatÖsszpontTesztVerdiktIdőMemória
base45/45
1Elfogadva0/01ms820 KiB
2Elfogadva0/013ms1588 KiB
3Elfogadva1/11ms820 KiB
4Elfogadva1/12ms820 KiB
5Elfogadva1/12ms820 KiB
6Elfogadva1/12ms800 KiB
7Elfogadva1/12ms928 KiB
8Elfogadva1/12ms820 KiB
9Elfogadva1/14ms1588 KiB
10Elfogadva1/14ms1588 KiB
11Elfogadva1/14ms1588 KiB
12Elfogadva1/11ms820 KiB
13Elfogadva1/12ms1036 KiB
14Elfogadva1/13ms1008 KiB
15Elfogadva1/12ms1048 KiB
16Elfogadva1/12ms820 KiB
17Elfogadva1/12ms820 KiB
18Elfogadva1/12ms820 KiB
19Elfogadva1/12ms820 KiB
20Elfogadva1/12ms820 KiB
21Elfogadva2/210ms1588 KiB
22Elfogadva2/213ms1764 KiB
23Elfogadva2/210ms1604 KiB
24Elfogadva3/323ms2356 KiB
25Elfogadva3/321ms2356 KiB
26Elfogadva3/37ms1808 KiB
27Elfogadva3/36ms1844 KiB
28Elfogadva3/39ms2720 KiB
29Elfogadva3/39ms2708 KiB
30Elfogadva3/310ms2572 KiB