Submission #1012680

#TimeUsernameProblemLanguageResultExecution timeMemory
1012680Muaath_5Islands (IOI08_islands)C++17
70 / 100
489 ms131072 KiB
#include <bits/stdc++.h> #define ll long long #define pii pair<int, int> using namespace std; const int N = 1e6+1; int n; vector<pair<int, ll>> adj[N]; map<pii, int> edge; map<pii, int> we; char vis[N]; vector<int> stck; vector<int> cyc; void dfs(int node, int par=0) { vis[node] = 1; stck.push_back(node); for (auto &[ch, cost] : adj[node]) { if (!vis[ch]) dfs(ch, node); else if (!cyc.size() && edge[{node, ch}] == 2) { cyc.push_back(node); cyc.push_back(ch); } else if (!cyc.size() && vis[ch] && ch != par) { bool st = 0; for (int cur : stck) { if (cur == ch) st = 1; if (st) cyc.push_back(cur); } } } stck.pop_back(); } pii remedge; int blk[2]; int mx[N]; ll farthest_dp(int node, int par=0) { mx[node] = node; ll mxdep = 0; for (auto [ch, cost] : adj[node]) { if (blk[0] == ch || blk[1] == ch || ch == par) continue; if (make_pair(node, ch) != remedge && make_pair(ch, node) != remedge) { ll mxdepch = farthest_dp(ch, node); if (mxdepch + cost > mxdep) { mxdep = mxdepch + cost; mx[node] = mx[ch]; } } } return mxdep; } ll pref[N], a[N]; ll solve_for(int node) { cyc.clear(); dfs(node); const ll L = cyc.size(); // cerr << "#" << node << ": "; // cerr << L << ": "; // for(int i:cyc)cerr<<i<<' '; // cerr<<"| "; // remove an edge from the cycle and find diameter if (L > 2) remedge = {cyc[0], cyc[1]}; else remedge = {-1, -1}; farthest_dp(node); int fr = mx[node]; ll diam = farthest_dp(fr); // a[i] = max depth of tree going from i not in cycle direction // prefix sums for (int i = 0; i < L; i++) { blk[0] = cyc[(i+1)%L]; blk[1] = cyc[(i-1+L)%L]; a[i] = farthest_dp(cyc[i]); } // for (int i = 0; i < L; i++) // cerr << a[i] << ' '; // cerr << "| "; // cost of path(i,j) = a[i] + a[j] + (p[i] - p[j]); // maintain maximum a[j] - p[j], and the answer for suffix i: // ll prvmx = 0; ll sol = 0; pref[0] = 0; for (int i = 1; i < L; i++) pref[i] = pref[i-1] + we[{cyc[i], cyc[i-1]}]; const ll LL = pref[L-1] + we[{cyc[L-1], cyc[0]}]; if (L == 2) { sol = *max_element(a, a+L) + we[{cyc[0], cyc[1]}]; goto RET; } prvmx = a[0]; for (int i = 1; i < L; i++) { sol = max(sol, a[i] + pref[i] + prvmx); prvmx = max(prvmx, a[i] - pref[i]); } prvmx = a[0]; for (int i = 1; i < L; i++) { sol = max(sol, LL + a[i] - pref[i] + prvmx); prvmx = max(prvmx, a[i] + pref[i]); } RET: return max(diam, sol); } signed main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin >> n; for (int i = 1; i <= n; i++) { int u; int w; cin >> u >> w; adj[i].push_back({u, w}); adj[u].push_back({i, w}); edge[{i,u}]++, edge[{u,i}]++; we[{i, u}] = we[{u, i}] = max(we[{i, u}], w); } ll sum = 0; for (int i = 1; i <= n; i++) if (!vis[i]) sum += solve_for(i); cout << sum; }
#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...