Submission #1106025

#TimeUsernameProblemLanguageResultExecution timeMemory
1106025dzhoz0Valley (BOI19_valley)C++17
100 / 100
134 ms58620 KiB
/* ghmt the cutie :3 UwU */ #include <bits/stdc++.h> using namespace std; #define int long long #define INF 1e18 #define f first #define s second #define pii pair<int, int> #define vi vector<int> const int MOD = 1'000'000'000 + 7; void setIO(string name = "") { ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0); #ifdef LOCAL freopen("inp.txt", "r", stdin); freopen("out.txt", "w", stdout); #else if (!name.empty()) { freopen((name + ".INP").c_str(), "r", stdin); freopen((name + ".OUT").c_str(), "w", stdout); } #endif } const int MAXN = 1e5; int n, s, q, e; vector<pii> g[MAXN + 5]; vector<array<int, 3>> edges; vi shops; vector<pii> queries; namespace sub12 { bool check() { if(n <= 100 && q <= 10'000) return true; return n <= 1000 && q <= 1000; } int st[MAXN + 5], en[MAXN + 5]; int timeDfs = 0; int f[MAXN + 5], h[MAXN + 5]; int up[MAXN + 5][20]; void pre_dfs(int u, int par) { st[u] = ++timeDfs; up[u][0] = par; for(int i = 1; i < 20; i++) { up[u][i] = up[up[u][i - 1]][i - 1]; } for(auto [v, w] : g[u]) { if(v == par) continue; f[v] = f[u] + w; h[v] = h[u] + 1; pre_dfs(v, u); } en[u] = ++timeDfs; } int LCA(int u, int v) { if(h[u] != h[v]) { if(h[u] < h[v]) swap(u, v); for(int i = 19; i >= 0; i--) { if(h[u] - h[v] >= (1 << i)) u = up[u][i]; } } if(u == v) return u; for(int i = 19; i >= 0; i--) { if(up[u][i] != up[v][i]) u = up[u][i], v = up[v][i]; } return up[u][0]; } bool is_ancestor(int u, int v) { return st[u] <= st[v] && en[v] <= en[u]; } void solve() { pre_dfs(e, e); for(auto &[u, v, w] : edges) { if(h[u] < h[v]) swap(u, v); } for(auto [id, r] : queries) { id--; if(!is_ancestor(edges[id][0], r)) { cout << "escaped\n"; continue; } int res = INF; for(int d : shops) { if(!is_ancestor(edges[id][0], d)) continue; int p = LCA(d, r); res = min(res, f[d] + f[r] - 2 * f[p]); } if(res != INF) { cout << res << '\n'; continue; } cout << "oo\n"; } } }; namespace sub3 { bool check() { if(n <= 100'000 && q <= 100'000 && s == n) return true; return false; } int h[MAXN + 5]; int st[MAXN + 5], en[MAXN + 5]; int timeDfs = 0; void pre_dfs(int u, int par) { st[u] = ++timeDfs; for(auto [v,w] : g[u]) { if(v == par) continue; h[v] = h[u] + 1; pre_dfs(v, u); } en[u] = ++timeDfs; } void solve() { pre_dfs(e, e); for(auto &[u, v, w] : edges) { if(h[u] < h[v]) swap(u, v); } for(auto [id, r] : queries) { id--; int u = edges[id][0], v = r; // cout << u << ' ' << v << '\n'; if(st[u] <= st[v] && en[v] <= en[u]) cout << "0\n"; else cout << "escaped" << '\n'; } } } namespace sub4 { bool check() { return n <= 100'000 && q <= 100'000; } int h[MAXN + 5]; int st[MAXN + 5], en[MAXN + 5]; int timeDfs = 0; bool is_shop[MAXN + 5]; int f[MAXN + 5]; int d[MAXN + 5]; int val[MAXN + 5]; // f[i] = min distance from root to shop in subtree i // d[i] = distance from root to i // val[i] - void pre_dfs(int u = e, int par = e) { st[u] = ++timeDfs; f[u] = (is_shop[u] ? d[u] : INF); for(auto [v, w] : g[u]) { if(v == par) continue; h[v] = h[u] + 1; d[v] = d[u] + w; pre_dfs(v, u); f[u] = min(f[u], f[v]); } val[u] = f[u] - 2 * d[u]; en[u] = ++timeDfs; } int up[MAXN + 5][20]; int mi[MAXN + 5][20]; void upmi_dfs(int u = e, int par = e) { up[u][0] = par, mi[u][0] = val[u]; for(int i = 1; i < 20; i++) { up[u][i] = up[up[u][i - 1]][i - 1]; mi[u][i] = min(mi[u][i - 1], mi[up[u][i - 1]][i - 1]); } for(auto [v, w] : g[u]) { if(v == par) continue; upmi_dfs(v, u); } } bool is_ancestor(int u, int v) { return st[u] <= st[v] && en[v] <= en[u]; } int mi_val(int root, int node) { int res = INF; for(int i = 19; i >= 0; i--) { if(is_ancestor(root, up[node][i])) { res = min(res, mi[node][i]); node = up[node][i]; } } return min(res, val[node]); } void solve() { for(int x : shops) is_shop[x] = 1; d[e] = 0; pre_dfs(); upmi_dfs(); // for(int i = 1; i <= n; i++) cout << d[i] << ' '; cout << '\n'; // for(int i = 1; i <= n; i++) cout << f[i] << ' '; cout << '\n'; // for(auto &[u, v, w] : edges) { if(h[u] < h[v]) swap(u, v); } for(auto [id, r] : queries) { id--; if(!is_ancestor(edges[id][0], r)) { cout << "escaped\n"; continue; } // cout << edges[id][0] << '\n'; if(f[edges[id][0]] == INF) { cout << "oo\n"; continue; } cout << mi_val(edges[id][0], r) + d[r] << '\n'; } } } void solve() { cin >> n >> s >> q >> e; for(int i = 1; i < n; i++) { int u, v, w; cin >> u >> v >> w; g[u].push_back({v, w}); g[v].push_back({u, w}); edges.push_back({u, v, w}); } shops.resize(s); for(int &i : shops) cin >> i; queries.resize(q); for(auto &it : queries) cin >> it.f >> it.s; if(sub12::check()) { sub12::solve(); return; } if(sub3::check()) { sub3::solve(); return; } if(sub4::check()) { sub4::solve(); return; } } signed main() { setIO(); int t = 1; // cin >> t; while (t--) solve(); }

Compilation message (stderr)

valley.cpp: In function 'void setIO(std::string)':
valley.cpp:28:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   28 |         freopen((name + ".INP").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:29:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   29 |         freopen((name + ".OUT").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...