Submission #1305966

#TimeUsernameProblemLanguageResultExecution timeMemory
1305966orzorzorzFireworks (APIO16_fireworks)C++20
0 / 100
13 ms19236 KiB
#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; const int MAXN = 600005; // We use an array of priority queues, one for each node priority_queue<long long> pq[MAXN]; vector<pair<int, int>> adj[MAXN]; int leaf_count[MAXN]; long long total_edge_weight = 0; void solve(int u) { if (adj[u].empty()) { // Leaf node initialization leaf_count[u] = 1; pq[u].push(0); pq[u].push(0); return; } for (auto& edge : adj[u]) { int v = edge.first; int w = edge.second; solve(v); leaf_count[u] += leaf_count[v]; // 1. Merge child's pq into parent's pq (Small-to-Large) if (pq[u].size() < pq[v].size()) { swap(pq[u], pq[v]); } while (!pq[v].empty()) { pq[u].push(pq[v].top()); pq[v].pop(); } } // 2. Adjust the slope for the edge connecting u to its parent // We only need to do this if u is not the root (1) // The slope increases by 1 at each breakpoint. To keep slope <= 1: while (pq[u].size() > leaf_count[u] + 1) { pq[u].pop(); } // 3. Take the two largest breakpoints (the flat [L, R] region) long long R = pq[u].top(); pq[u].pop(); long long L = pq[u].top(); pq[u].pop(); // 4. Shift them by the edge weight leading to u // Note: In this specific implementation, we handle the edge of 'u' // inside the 'solve(u)' call. } // Refined Main Loop for the Edge Shift Logic int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; vector<int> parent(n + m + 1); vector<int> weight(n + m + 1); for (int i = 2; i <= n + m; i++) { cin >> parent[i] >> weight[i]; adj[parent[i]].push_back({i, weight[i]}); total_edge_weight += weight[i]; } // Post-order traversal logic (Bottom-up) for (int i = n + m; i >= 2; i--) { if (i > n) { // Leaf leaf_count[i] = 1; pq[i].push(0); pq[i].push(0); } else { while (pq[i].size() > leaf_count[i] + 1) pq[i].pop(); long long R = pq[i].top(); pq[i].pop(); long long L = pq[i].top(); pq[i].pop(); pq[i].push(L + weight[i]); pq[i].push(R + weight[i]); } // Merge into parent int p = parent[i]; leaf_count[p] += leaf_count[i]; if (pq[p].size() < pq[i].size()) swap(pq[p], pq[i]); while (!pq[i].empty()) { pq[p].push(pq[i].top()); pq[i].pop(); } } // Final Root (Node 1) Processing // Slope should be 0 at the minimum. while (pq[1].size() > leaf_count[1]) { pq[1].pop(); } long long ans = total_edge_weight; while (!pq[1].empty()) { ans -= pq[1].top(); pq[1].pop(); } cout << ans << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...