#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[1000001];
int vis[1000001];
int color[1000001];
int tot;
int cnt;
int fa[1000001];
int root[1000001];
vector<int>b[1000001];
int dp[1000001][2];// 点i选与不选
int g[1000001][2];// 在环上跑
void dfs(int x) {
vis[x]=1;
color[x]=tot;
for(int i=0 ; i<b[x].size(); i++) {
int v=b[x][i];
if(vis[v]==0) {
dfs(v);
} else if(vis[v]==1&&color[v]==tot) {
int p=x;
while(1) {
root[++cnt]=p;
if(p==v) return ;
p=fa[p];
}
}
}
}
void dfs2(int x) {
dp[x][0]=0;
dp[x][1]=a[x];
for(int i=0; i<b[x].size(); i++) {
int v=b[x][i];
if(vis[v]) continue;
dfs2(v);
dp[x][1]+=dp[v][0];
dp[x][0]+=max(dp[v][1],dp[v][0]);
}
}
void dfs3(int x) {
g[x][0]=dp[x][0];
g[x][1]=dp[x][1];
vis[x]=0;
for(int i=0; i<b[x].size(); i++) {
int v=b[x][i];
if(vis[v]==0) continue;
dfs3(v);
g[x][1]+=g[v][0];
g[x][0]+=max(g[v][1],g[v][0]);
}
}
signed main() {
cin>>n;
for(int i=1; i<=n; i++) {
scanf("%lld%lld",&a[i],&fa[i]);
b[fa[i]].push_back(i);
}
for(int i=1; i<=n; i++) {
if(vis[i]==0) {
tot++;
dfs(i);
}
}
memset(vis,0,sizeof(vis));
for(int i=1; i<=cnt; i++) vis[root[i]]=1;
for(int i=1; i<=cnt; i++) {
dfs2(root[i]);
}
int ans=0;
for(int i=1; i<=cnt; i++) {
if(vis[root[i]]==1) {
dfs3(root[i]);
ans+=max(g[root[i]][0],g[root[i]][1]);
}
}
cout<<ans<<endl;
return 0;
}
/*
20
0 2
0 3
0 4
0 1
0 3
0 3
0 5
0 5
0 6
0 2
0 10
0 10
0 1
0 1
0 2
0 2
0 2
0 4
0 18
0 19
*/
我感觉是树形dp完后在环上跑的dp炸了,只对了前6个点(n<=100 ?).但自己不会改