Submission #687657

#TimeUsernameProblemLanguageResultExecution timeMemory
687657finn__Islands (IOI08_islands)C++17
90 / 100
1508 ms131072 KiB
#include <bits/stdc++.h> using namespace std; vector<vector<pair<unsigned, unsigned>>> g; pair<int, unsigned> find_cycle(unsigned u, vector<unsigned> &c, vector<bool> &vis, unsigned p = -1) { if (vis[u]) return {1, u}; vis[u] = 1; for (auto const &[v, w] : g[u]) if (v != p) { auto const [b, x] = find_cycle(v, c, vis, u); if (b == 1) { c.push_back(u); return {u == x ? 2 : 1, x}; } if (b == 2) return {2, x}; } return {0, UINT_MAX}; } // Returns (longest path inside subtree, longest path to root) pair<int64_t, int64_t> longest_tree_path(unsigned u, unsigned p = -1) { pair<int64_t, int64_t> ans = {0, 0}; for (auto const &[v, w] : g[u]) { if (v != p) { auto const [sl, rl] = longest_tree_path(v, u); ans.first = max(ans.first, max(sl, ans.second + rl + w)); ans.second = max(ans.second, rl + w); } } return ans; } int64_t longest_simple_path(unsigned u, vector<bool> &cvis) { vector<unsigned> c; find_cycle(u, c, cvis); if (c.empty()) return longest_tree_path(u).first; size_t const m = c.size(); vector<int64_t> root_paths(c.size()); int64_t ans = 0; vector<unsigned> pre_dis(c.size()), next_dis(c.size()); int64_t sum = 0; for (size_t i = 0; i < m; i++) { auto it = lower_bound(g[c[i]].begin(), g[c[i]].end(), make_pair(c[(i + 1) % m], 0U)); assert(it != g[c[i]].end()); next_dis[i] = it->second; sum += it->second; g[c[i]].erase(it); auto jt = lower_bound(g[c[i]].begin(), g[c[i]].end(), make_pair(c[(i - 1 + m) % m], 0U)); assert(jt != g[c[i]].end()); pre_dis[i] = jt->second; g[c[i]].erase(jt); } for (size_t i = 0; i < m; i++) { auto const [sl, rl] = longest_tree_path(c[i]); ans = max(ans, sl); root_paths[i] = rl; } int64_t dp1 = 0, dp2 = 0, prefix_sum = 0; for (size_t i = 0; i < m; i++) { if (i) { ans = max(ans, root_paths[i] + prefix_sum + dp1); ans = max(ans, sum + root_paths[i] - prefix_sum + dp2); } dp1 = max(dp1, root_paths[i] - prefix_sum); dp2 = max(dp2, root_paths[i] + prefix_sum); prefix_sum += next_dis[i]; } return ans; } void mark_component(unsigned u, vector<bool> &vis) { vis[u] = 1; for (auto const &[v, w] : g[u]) if (!vis[v]) mark_component(v, vis); } bool edge_cmp(pair<unsigned, unsigned> const &a, pair<unsigned, unsigned> const &b) { return a.first == b.first; } int main() { size_t n; cin >> n; g = vector<vector<pair<unsigned, unsigned>>>(n); for (size_t i = 0; i < n; i++) { unsigned u, w; cin >> u >> w; g[i].emplace_back(u - 1, w); g[u - 1].emplace_back(i, w); } for (unsigned i = 0; i < n; i++) { sort(g[i].begin(), g[i].end(), greater<pair<unsigned, unsigned>>()); g[i].resize(unique(g[i].begin(), g[i].end(), edge_cmp) - g[i].begin()); sort(g[i].begin(), g[i].end()); } vector<bool> vis(n, 0), cvis(n, 0); int64_t max_distance = 0; for (unsigned i = 0; i < n; i++) { if (!vis[i]) { mark_component(i, vis); max_distance += longest_simple_path(i, cvis); } } cout << max_distance << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...