Editorial for Công Sở
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
#include <iostream> #include <vector> #include <algorithm> #include <limits> #include <array> #include <cassert> using namespace std; void solve() { int n; cin >> n; vector<int> p(n); vector<int> a(n); vector<array<vector<int64_t>, 2>> f(n); int64_t constexpr INF = numeric_limits<int64_t>::max() / 4; int constexpr OMITTED = 0; int constexpr CHOSEN = 1; for (int i = 1; i < n; ++i) { cin >> p[i]; p[i]--; } for (int i = 1; i < n; ++i) { cin >> a[i]; } for (int i = 1; i < n; ++i) { int x; cin >> x; a[i] = min(a[i], x); } for (int i = 0; i < n; ++i) { f[i][OMITTED] = {0, INF}; f[i][CHOSEN] = {INF, 0}; } for (int i = n - 1; i > 0; --i) { int j = p[i]; int ni = f[i][CHOSEN].size() - 1; int nj = f[j][CHOSEN].size() - 1; f[j][OMITTED].resize(ni + nj + 1, INF); f[j][CHOSEN].resize(ni + nj + 1, INF); for (int s = ni + nj; s >= 0; --s) { for (int x = max(0, s - nj); x <= min(ni, s); ++x) { f[j][OMITTED][s] = min(f[j][OMITTED][s], f[i][CHOSEN][x] + f[j][OMITTED][s - x]); f[j][OMITTED][s] = min(f[j][OMITTED][s], f[i][OMITTED][x] + f[j][OMITTED][s - x]); f[j][CHOSEN][s] = min(f[j][CHOSEN][s], f[i][CHOSEN][x] + f[j][CHOSEN][s - x] + a[i]); f[j][CHOSEN][s] = min(f[j][CHOSEN][s], f[i][OMITTED][x] + f[j][CHOSEN][s - x]); } } } assert(f[0][CHOSEN].size() == n + 1); for (int i = 1; i <= n; ++i) { cout << min(f[0][OMITTED][i], f[0][CHOSEN][i]) << " "; } cout << endl; } int main() { cin.tie(0)->sync_with_stdio(0); int t; cin >> t; while (t--) { solve(); } }
Comments