제출 #555568

#제출 시각아이디문제언어결과실행 시간메모리
555568alextodoranIslands (IOI08_islands)C++17
90 / 100
1029 ms131072 KiB
/** ____ ____ ____ ____ ____ ||a |||t |||o |||d |||o || ||__|||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|/__\| **/ #include <bits/stdc++.h> #define order curr using namespace std; typedef long long ll; const int N_MAX = 1000000; int N; int to[N_MAX + 2], len[N_MAX + 2]; vector <int> adj[N_MAX + 2]; int other (int u, int v) { return (u == v ? to[u] : u); } int par[N_MAX + 2]; int depth[N_MAX + 2]; pair <int, int> backEdge; int curr[N_MAX + 2]; void dfs (int u) { depth[u] = 0; while (u != 0) { if (curr[u] <= (int) adj[u].size()) { int x = (curr[u] < (int) adj[u].size() ? adj[u][curr[u]] : u); curr[u]++; int v = other(x, u); if (depth[v] == -1) { par[v] = x; depth[v] = depth[u] + 1; u = v; } else if (depth[v] > depth[u]) { backEdge = make_pair(u, x); } } else { u = other(par[u], u); } } } bitset <N_MAX + 2> root; ll maxAny[N_MAX + 2]; ll maxDown[N_MAX + 2]; queue <int> q; //int order[N_MAX + 2]; void compute (int s) { q.push(s); depth[s] = 0; int cnt = 0; while (q.empty() == false) { int u = q.front(); q.pop(); order[++cnt] = u; for (int x : adj[u]) { int v = other(x, u); if (depth[v] == -1 && root[v] == false) { q.push(v); depth[v] = depth[u] + 1; } } { int v = to[u]; if (depth[v] == -1 && root[v] == false) { q.push(v); depth[v] = depth[u] + 1; } } } for (int i = cnt; i >= 1; i--) { int u = order[i]; ll maxDown1 = 0, maxDown2 = 0; for (int x : adj[u]) { int v = other(x, u); if (depth[u] < depth[v] && root[v] == false) { maxAny[u] = max(maxAny[u], maxAny[v]); maxDown[u] = max(maxDown[u], maxDown[v] + len[x]); ll here = maxDown[v] + len[x]; if (here >= maxDown1) { maxDown2 = maxDown1; maxDown1 = here; } else if (here > maxDown2) { maxDown2 = here; } } } { int v = to[u]; if (depth[u] < depth[v] && root[v] == false) { maxAny[u] = max(maxAny[u], maxAny[v]); maxDown[u] = max(maxDown[u], maxDown[v] + len[u]); ll here = maxDown[v] + len[u]; if (here >= maxDown1) { maxDown2 = maxDown1; maxDown1 = here; } else if (here > maxDown2) { maxDown2 = here; } } } maxAny[u] = max(maxAny[u], maxDown1 + maxDown2); } } int roots[N_MAX + 2]; int group[N_MAX + 2]; int cntRoots; int cntGroups; multiset <ll> s; int main () { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> N; for (int u = 1; u <= N; u++) { cin >> to[u] >> len[u]; adj[to[u]].push_back(u); } fill(depth + 1, depth + N + 1, -1); for (int u = 1; u <= N; u++) { if (depth[u] == -1) { dfs(u); int v1, x; tie(v1, x) = backEdge; int v2 = other(x, v1); swap(v1, v2); par[v2] = x; cntGroups++; int v = v1; while (v != v2) { root[v] = true; roots[++cntRoots] = v; group[cntRoots] = cntGroups; v = other(par[v], v); } root[v] = true; roots[++cntRoots] = v; group[cntRoots] = cntGroups; } } fill(depth + 1, depth + N + 1, -1); for (int u = 1; u <= N; u++) { if (root[u] == true) { compute(u); } } ll answer = 0; for (int g = 1, i = 1; g <= cntGroups; g++) { int j = i; while (j < cntRoots && group[j + 1] == g) { j++; } ll totalLen = 0; ll maxLen = 0; for (int k = i; k <= j; k++) { int u = roots[k]; totalLen += len[par[u]]; maxLen = max(maxLen, maxAny[u]); } ll leng = 0; for (int k = j; k > i; k--) { int u = roots[k]; leng += len[par[u]]; s.insert(maxDown[u] + leng); } ll lazy = 0; for (int k = i, u = roots[i]; k <= j; k++) { assert(s.empty() == false); maxLen = max(maxLen, *s.rbegin() + lazy + maxDown[u]); s.insert(maxDown[u] - lazy); lazy += len[par[u]]; u = other(par[u], u); assert(s.find((maxDown[u] + totalLen) - lazy) != s.end()); s.erase(s.find((maxDown[u] + totalLen) - lazy)); } answer += maxLen; s.clear(); i = j + 1; } cout << answer << "\n"; return 0; }
#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...