Submission #726039

#TimeUsernameProblemLanguageResultExecution timeMemory
726039JohannVillage (BOI20_village)C++14
75 / 100
130 ms22464 KiB
#include "bits/stdc++.h" using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<vi> vvi; typedef vector<pii> vpii; typedef vector<vpii> vvpii; #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() int N; vvi adj; // Code for the mini length vi dpP, dpN; vi ans_mini; int miniCheck = 0; void dfs_mini(int v, int p) { if (sz(adj[v]) == 1 && v != p) { // leaf dpN[v] = 0; dpP[v] = INT_MAX; return; } for (int u : adj[v]) if (u != p) dfs_mini(u, v); dpN[v] = 0; for (int u : adj[v]) if (u != p) dpN[v] += min(dpP[u], dpN[u] + 2); for (int u : adj[v]) if (u != p) { int tmp = dpN[v] - min(dpP[u], dpN[u] + 2) + min(dpP[u], dpN[u]) + 2; dpP[v] = min(dpP[v], tmp); } } void reconstruct_dpP(int v, int p); void reconstruct_dpN(int v, int p, int except); void reconstruct_dpN(int v, int p, int except = -1) { if (sz(adj[v]) == 1 && v != p) return; // leaf for (int u : adj[v]) { if (u == p) continue; if (u == except) { swap(ans_mini[v], ans_mini[u]); miniCheck += 2; if (dpP[u] < dpN[u]) reconstruct_dpP(u, v); else reconstruct_dpN(u, v); } else if (dpP[u] < dpN[u] + 2) reconstruct_dpP(u, v); else { swap(ans_mini[v], ans_mini[u]); miniCheck += 2; reconstruct_dpN(u, v); } } } void reconstruct_dpP(int v, int p) { if (sz(adj[v]) == 1 && v != p) return; // leaf int w = -1; for (int u : adj[v]) if (u != p) { int tmp = dpN[v] - min(dpP[u], dpN[u] + 2) + min(dpP[u], dpN[u]) + 2; if (dpP[v] == tmp) { w = u; break; } } reconstruct_dpN(v, p, w); } // code for the maxi part vi subsize, swapsRequired; vvi contains; vi ans_maxi; void dfs_maxi(int v, int p) { subsize[v] = 1; for (int u : adj[v]) if (u != p) { dfs_maxi(u, v); subsize[v] += subsize[u]; } } int find_split(int v) { // v must be root of the tree with respect to subsize pii maxSub = {-1, -1}; for (int u : adj[v]) maxSub = max(maxSub, {subsize[u], u}); if (maxSub.first <= N / 2) return v; subsize[v] = N - maxSub.first; subsize[maxSub.second] = N; return find_split(maxSub.second); } void collect(int v, int p) { contains[v].push_back(v); for (int u : adj[v]) if (u != p) { collect(u, v); swapsRequired[v] += swapsRequired[u] + subsize[u]; if (v != p) { if (sz(contains[u]) > sz(contains[v])) swap(contains[u], contains[v]); while (!contains[u].empty()) contains[v].push_back(contains[u].back()), contains[u].pop_back(); } } } void distribute(int v) { vi places; places.push_back(v); for (int u : adj[v]) places.push_back(u); sort(all(places), [&](int a, int b) { return sz(contains[a]) > sz(contains[b]); }); queue<int> todo; for (int u : places) for (int w : contains[u]) todo.push(w); for (int i = 0; i < sz(places); ++i) for (int u : contains[places[(i + 1) % sz(places)]]) ans_maxi[u] = todo.front(), todo.pop(); } // main int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N; adj.resize(N); for (int i = 0, a, b; i < N - 1; ++i) { cin >> a >> b, --a, --b; adj[a].push_back(b), adj[b].push_back(a); } // mini dpP.assign(N, INT_MAX), dpN.assign(N, INT_MAX); dfs_mini(0, 0); ans_mini.resize(N); iota(all(ans_mini), 1); reconstruct_dpP(0, 0); // maxi subsize.resize(N); dfs_maxi(0, 0); int center = find_split(0); contains.resize(N); swapsRequired.assign(N, 0); collect(center, center); ans_maxi.resize(N); distribute(center); // ans cout << dpP[0] << " "; cout << 2 * swapsRequired[center] << endl; assert(miniCheck == dpP[0]); for (int v : ans_mini) cout << v << " "; cout << endl; for (int v : ans_maxi) cout << v + 1 << " "; cout << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...