\[ dp[u][0]=\sum_{i=1}^{q}Max(dp[son[i]][0],dp[son[i]][1]);\dp[u][1]=\sum_{i=1}^{q}dp[son[i]][0] \]
\[ f[u][0]=Max(f[pre][0],f[pre][1])+dp[u][0];\f[u][1]=f[pre][0]+dp[u][1]; \]
\[ f[u][0][0]=Max(f[pre][0][0],f[pre][0][1])+dp[u][0];\f[u][1][0]=Max(f[pre][1][0],f[pre][1][1])+dp[u][0];\f[u][0][1]=f[pre][0][0]+dp[u][1];\f[u][1][1]=f[pre][1][0]+dp[u][1]; \]
\[ f[s][0][0]=dp[s][0],f[s][1][1]=dp[s][1],dp[s][1][0]=dp[s][0][1]=-INF \]
\[ Max{\{}f[t][1][0],f[t][0][0],f[t][0][1]{\}} \]
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000001
using namespace std;
struct edge{
int to,next;
edge(){}
edge(const int &_to,const int &_next){ to=_to,next=_next; }
}e[maxn<<1];
int head[maxn],k;
int dfn[maxn],fa[maxn],tot;
bool inloop[maxn],vis[maxn],mark[maxn];
long long dp[maxn][2],f[maxn][2][2],ans;
int val[maxn],n;
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
inline void add(const int &u,const int &v){ e[k]=edge(v,head[u]),head[u]=k++; }
void dfs_getloop(int u){
dfn[u]=++tot;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]) continue;
if(!dfn[v]) fa[v]=u,dfs_getloop(v);
else if(dfn[u]<dfn[v]){
inloop[v]=true;
do{ inloop[fa[v]]=true,v=fa[v]; }while(v!=u);
}
}
}
void dfs_dp(int u){
dp[u][1]=val[u],vis[u]=true;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(inloop[v]||vis[v]) continue;
dfs_dp(v);
dp[u][0]+=max(dp[v][0],dp[v][1]);
dp[u][1]+=dp[v][0];
}
}
void dp_loop(int u){
bool flag=true; mark[u]=true;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(!inloop[v]||mark[v]) continue;
f[v][0][0]=max(f[u][0][0],f[u][0][1])+dp[v][0],f[v][0][1]=f[u][0][0]+dp[v][1];
f[v][1][0]=max(f[u][1][0],f[u][1][1])+dp[v][0],f[v][1][1]=f[u][1][0]+dp[v][1];
dp_loop(v),flag=false;
}
if(flag) ans+=max(f[u][1][0],max(f[u][0][0],f[u][0][1]));
}
int main(){
memset(head,-1,sizeof head);
n=read();
for(register int i=1;i<=n;i++){
val[i]=read(); int v=read();
add(v,i),add(i,v);
}
for(register int i=1;i<=n;i++) if(!dfn[i]) dfs_getloop(i);
for(register int i=1;i<=n;i++) if(!vis[i]&&inloop[i]) dfs_dp(i);
for(register int i=1;i<=n;i++) if(!mark[i]&&inloop[i])
f[i][0][0]=dp[i][0],f[i][1][1]=dp[i][1],f[i][1][0]=f[i][0][1]=0x8080808080808080,dp_loop(i);
printf("%lld\n",ans);
return 0;
}
原文:https://www.cnblogs.com/akura/p/10919980.html