#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 time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |