和<没有上司的舞会>一样,但树上多了条边
断掉环上一条边,两个点分别做dp ,取max
#include <iostream>
#include <algorithm>
using namespace std ;
const int N=1e6+5,M=2*N;
#define int long long
int n,vis[N],a[N];
int rt1,rt2,f[N][2];
int nxt[M],go[M],hd[N],all=1;
int e;
void add(int x,int y){
go[++all]=y,nxt[all]=hd[x],hd[x]=all;
}
void find(int x,int fa){
vis[x]=1;
int i,y;
for(i=hd[x];i;i=nxt[i]){
y=go[i]; if(y==fa) continue;
if(vis[y]){
rt1=x,rt2=y; e=i; break;
}
find(y,x);
}
}
void dp(int x,int fa){
int i,y;
vis[x]=1;
f[x][1]=a[x];
f[x][0]=0;
for(i=hd[x];i;i=nxt[i]){
y=go[i]; if(y==fa||i==e||(i^1)==e) continue;
dp(y,x);
f[x][0]+=max(f[y][1],f[y][0]);
f[x][1]+=f[y][0];
}
}
signed main(){
int i,x,t1,t2,ans=0;
cin>>n;
for(i=1;i<=n;i++){
cin>>a[i]>>x;
add(x,i);add(i,x);
}
for(i=1;i<=n;i++){
if(vis[i]) continue;
find(i,-1);
dp(rt1,-1); t1=f[rt1][0];
dp(rt2,-1); t2=f[rt2][0];
ans+=max(t1,t2);
}
cout<<ans;
}
浙公网安备 33010602011771号