70分WA求助 (在b站上看了董晓老师的视频,记了思路照着打了一遍,基本没区别,但最后3个点WA了qwq,莫名其妙地输出了负数,求助大佬qwq)
#include<cstdio>
#include<iostream>
using namespace std;
int mx(int m1,int m2)
{
if(m1>m2) return m1;
return m2;
}
int n,m,r1,r2,w[1000010];
long long ans=0,res;
struct Edge
{
int nex,to;
}E[1000010];
int head[1000010]={0};
bool vis[1000010]={false};
void find(int frt,int fnw)//Look for a ring(frt->RooT_node|fnw->NoW_node)
{
//printf("!rt:%d nw:%d\n",frt,fnw);
vis[fnw]=true;
int temp=head[fnw];
while(temp)
{
if(E[temp].to==frt)//find a ring
{
r1=frt;
r2=fnw;
//printf("@%d %d\n",r1,r2);
return;
}
if(vis[E[temp].to])
{
temp=E[temp].nex;//the next edge
continue;//son has benn visited, to be continued~
}
find(frt,E[temp].to);//visit son
temp=E[temp].nex;//the next edge
}
return;
}
long long dp[1000010][2]={0};//dp[k][0]->no|dp[k][1]->yes
void dfs(int drt,int dnw)//DP(drt->RooT_node|dnw->NoW_node)
{
vis[dnw]=true;
dp[dnw][0]=0;
dp[dnw][1]=w[dnw];
int temp=head[dnw];
while(temp)
{
if(E[temp].to==drt)//this edge has been deleted(can NOT visit the root)
{
temp=E[temp].nex;//the next edge
continue;//come to next edge
}
dfs(drt,E[temp].to);//visit son
dp[dnw][0]+=mx(dp[E[temp].to][0],dp[E[temp].to][1]);//dp
dp[dnw][1]+=dp[E[temp].to][0];//dp
temp=E[temp].nex;//the next edge
}
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)//input
{
scanf("%d%d",&w[i],&m);
E[i].to=i;//AddEdge
E[i].nex=head[m];
head[m]=i;
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
r1=r2=0;//初始化
find(i,i);//look for a ring
if(r1)//没有环别瞎搞
{
dfs(r1,r1);
res=dp[r1][0];
//!!!如果这里不先储存dp[r1][0],经过下一次dfs后,dp[r1][0]可能被覆盖
dfs(r2,r2);
ans+=mx(res,dp[r2][0]);
}
}
}
printf("%lld",ans);
return 0;
}