Code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000010, M = 2 * N;
int n, a[N], res, f[N][2], s1, f1, s2, f2;
bool st[N];
int h[N], e[M], ne[M], idx = 1;
vector<int> path, s;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
void dfs(int u, int father)
{
if (st[u])
{
s1 = path.back();
s2 = path[(int)path.size() - 2];
return;
}
else s.push_back(u);
st[u] = true;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == father) continue;
path.push_back(j);
dfs(j, u);
if (s1 != -1 || s2 != -1) return;
}
path.pop_back();
}
void dp(int u, int father)
{
st[u] = true;
f[u][0] = 0;
f[u][1] = a[u];
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j == father) continue;
if (u == s1 && j == s2) continue;
//cout << u << ">> " << j << endl;
if (u == s2 && j == s1) continue;
// cout << u << " -> " << j << endl;
dp(j, u);
f[u][0] += max(f[j][0], f[j][1]);
f[u][1] += f[j][0];
}
f[s1][f1] = f[s2][f2] = 0;
}
void work(int x)
{
int maxn = 0;
path.clear(); s.clear();
path.push_back(x);
s1 = s2 = -1;
dfs(x, -1);
// cout << s.size() << endl;
if (s1 != -1 && s2 != -1 && s.size() == 2)
{
res += max(a[s1], a[s2]);
return;
}
// cout << s1 << " " << s2 << endl;
memset(f, 0, sizeof f);
f1 = f2 = 1; dp(x, -1);
maxn = max(maxn, max(f[x][0], f[x][1]));
f1 = 1, f2 = 0; dp(x, -1);
maxn = max(maxn, max(f[x][0], f[x][1]));
f1 = 0, f2 = 1; dp(x, -1);
maxn = max(maxn, max(f[x][0], f[x][1]));
res += maxn;
}
signed main()
{
memset(h, -1, sizeof h);
cin >> n;
for (int i = 1; i <= n; i ++ )
{
int x;
cin >> a[i] >> x;
add(i, x), add(x, i);
}
for (int i = 1; i <= n; i ++ )
if (!st[i]) work(i);
cout << res << endl;
return 0;
}