#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
//#pragma GCC target("popcnt")
using namespace __gnu_pbds;
using namespace std;
using ordered_set = tree<int, null_type, less_equal<>, rb_tree_tag, tree_order_statistics_node_update>;
#define popcount __builtin_popcountll
#define all(a) (a).begin(), (a).end()
#define int long long
vector<pair<int,int>> adj[1'000'000];
int par[1'000'000], len[1'000'000];
bool visited[1'000'000];
void dfs(int u);
long long longest(int u, int p1, int p2) {
long long ans = 0;
for (auto [v, w] : adj[u]) if (v != p1 && v != p2) {
ans = max(ans, longest(v, u, u) + w);
}
return ans;
}
long long solve_comp(int start) {
int fast = start, slow = start;
do {
fast = par[par[fast]];
slow = par[slow];
} while (fast != slow);
vector<int> cycle, lens;
do {
cycle.push_back(slow);
lens.push_back(len[slow]);
slow = par[slow];
} while (fast != slow);
int k = cycle.size();
vector<long long> vals(cycle.size()), pref(cycle.size());
for (int i = 0; i < k; i++)
vals[i] = longest(cycle[i], cycle[(i+1) % k], cycle[(i-1+k) % k]);
for (int i = 1; i < k; i++)
pref[i] = pref[i-1] + lens[i-1];
// j -> i = vals[i] + vals[j] + pref[i] - pref[j] -> (vals[i] + pref[i]) + (vals[j] - pref[j])
long long mx = 0, ans = 0;
for (int i = 0; i < k; i++) {
mx = max(mx, vals[i] - pref[i]);
ans = max(ans, vals[i] + pref[i] + mx);
}
// i -> j = vals[i] + vals[j] + L - (pref[i] - pref[j]) -> L + (vals[i] - pref[i]) + (vals[j] + pref[j])
long long L = accumulate(all(lens), 0LL);
mx = -1e18;
for (int i = 0; i < k; i++) {
ans = max(ans, L + vals[i] - pref[i] + mx);
mx = max(mx, vals[i] + pref[i]);
}
dfs(start);
return ans;
}
void dfs(int u) {
visited[u] = true;
for (auto [v, w] : adj[u]) if (!visited[v]) dfs(v);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int n; cin >> n;
for (int i = 0; i < n; i++) {
cin >> par[i] >> len[i];
par[i]--;
adj[i].emplace_back(par[i], len[i]);
adj[par[i]].emplace_back(i, len[i]);
}
long long ans = 0;
for (int i = 0; i < n; i++) if (!visited[i]) {
ans += solve_comp(i);
}
cout << ans;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |