是个基环树
就是早期仙人掌没引入OI的时候把树搞难的办法
做法有点像小C的独立集(我好毒啊仙人掌的题似乎要难一点吧)
于是找环(DSU即可)
然后随便断环
就完了
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
typedef int INT;
#define int long long
inline void read(int &x){
x=0;
char ch=getchar();
int f=1;
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
struct Front_star{
int u,v,nxt;
}e[N<<2];
int cnt=0;
int first[N]={};
void add(int u,int v){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].nxt=first[u];
first[u]=cnt;
}
int fa[N]={};
inline int GetFa(int x){
if(fa[x]==x)return x;
else return fa[x]=GetFa(fa[x]);
}
inline void Union(int x,int y){
fa[GetFa(x)]=GetFa(y);
}
int n,tot=0;
int val[N]={};
int St[N]={};
int Ed[N]={};
int f[N];
int g[N];
inline void Solve(int x,int fat){
// cout<<x<<" "<<fat<<'\n';
f[x]=val[x];
g[x]=0;
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(v==fat)continue;
Solve(v,x);
g[x]+=max(g[v],f[v]);
f[x]+=g[v];
}
}
INT main(){
// freopen("P2607.in","r",stdin);
read(n);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=n;i++){
read(val[i]);
int u=i;
int v;
read(v);
if(GetFa(u)!=GetFa(v)){
add(u,v);
add(v,u);
Union(u,v);
}
else{
St[++tot]=u;
Ed[tot] =v;
}
}
int ans=0;
for(int i=1;i<=tot;i++){
Solve(St[i],0);
int t=g[St[i]];
Solve(Ed[i],0);
t=max(t,g[Ed[i]]);
ans+=t;
}
cout<<ans<<'\n';
return 0;
}