Submission #757039

#TimeUsernameProblemLanguageResultExecution timeMemory
757039SanguineChameleonIslands (IOI08_islands)C++17
90 / 100
848 ms131072 KiB
#include <bits/stdc++.h> using namespace std; void just_do_it(); int main() { #ifdef KAMIRULEZ freopen("kamirulez.inp", "r", stdin); freopen("kamirulez.out", "w", stdout); #endif ios_base::sync_with_stdio(0); cin.tie(0); just_do_it(); return 0; } const int maxn = 1e6 + 20; int to[maxn]; pair<int, int> edges[maxn * 2]; int adj_pt[maxn]; int par[maxn]; int len[maxn]; long long dp[maxn]; bool flag[maxn]; bool is_cycle[maxn]; int cycle[maxn]; bool head[maxn]; int sz; void dfs1(int u) { flag[u] = true; for (int pt = adj_pt[u]; edges[pt].first == u; pt++) { int id = edges[pt].second; if (id == par[u]) { continue; } int v = id ^ to[id] ^ u; if (!flag[v]) { par[v] = id; dfs1(v); } else { int cur = u; while (cur != v) { if (par[cur] == -1) { break; } cur = par[cur] ^ to[par[cur]] ^ cur; } if (cur == v) { cur = u; while (cur != v) { cycle[sz] = cur; head[sz] = (par[cur] == cur); sz++; cur = par[cur] ^ to[par[cur]] ^ cur; } cycle[sz] = v; head[sz] = (id == v); sz++; } } } } long long res; void dfs2(int u, int p) { dp[u] = 0; long long mx1 = 0; long long mx2 = 0; for (int pt = adj_pt[u]; edges[pt].first == u; pt++) { int id = edges[pt].second; int v = id ^ to[id] ^ u; if (v != p && !is_cycle[v]) { dfs2(v, u); dp[u] = max(dp[u], dp[v] + len[id]); if (dp[v] + len[id] > mx1) { mx2 = mx1; mx1 = dp[v] + len[id]; } else if (dp[v] + len[id] > mx2) { mx2 = dp[v] + len[id]; } } } res = max(res, mx1 + mx2); } long long calc_max(int u) { is_cycle[u] = false; dfs2(u, -1); is_cycle[u] = true; return dp[u]; } long long solve() { res = 0; long long sum = 0; for (int i = 0; i < sz; i++) { is_cycle[cycle[i]] = true; sum += (head[i] ? len[cycle[i]] : len[cycle[(i + 1) % sz]]); } long long dist = 0; long long mx1 = calc_max(cycle[0]); long long mx2 = mx1; for (int i = 1; i < sz; i++) { dist += (head[i - 1] ? len[cycle[i - 1]] : len[cycle[i]]); long long max_depth = calc_max(cycle[i]); res = max(res, dist + max_depth + mx1); res = max(res, sum - dist + max_depth + mx2); mx1 = max(mx1, max_depth - dist); mx2 = max(mx2, max_depth + dist); } return res; } void just_do_it() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> to[i] >> len[i]; edges[i * 2 - 1].first = i; edges[i * 2 - 1].second = i; edges[i * 2].first = to[i]; edges[i * 2].second = i; } sort(edges + 1, edges + n * 2 + 1); for (int i = 1; i <= n * 2; i++) { if (edges[i].first != edges[i - 1].first) { adj_pt[edges[i].first] = i; } } long long res = 0; for (int u = 1; u <= n; u++) { if (!flag[u]) { sz = 0; par[u] = -1; dfs1(u); res += solve(); } } cout << res; }
#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...