很基础的题目,前向星建图,dfs每次记录包括和不包括当前节点的权值max,一开始没考虑权值为负数wrong了一次,将状态转移方程改了一下就ok了。
ACcode:
#include<cstdio>
#include<cstring>
const int nsize=6666;
int w[nsize],v[nsize],h[nsize],dp[5];
int head[nsize],next[nsize],e[nsize],top;
void add(int p,int s,int k)
{
next[k]=head[p];
e[k]=s;
head[p]=k;
}
int Max(int a1,int a2)
{
return a1>a2?a1:a2;
}
void dfs(int rt)
{
int a1=0,a0=0;
v[rt]=0,a1=w[rt];
for (int i=head[rt];i!=-1;i=next[i])
{
if (v[e[i]])
{
dfs(e[i]);
a0+=Max(dp[1],dp[0]);
a1+=dp[0];
}
}
dp[0]=a0,dp[1]=Max(0,a1);
}
int main()
{
int n,p,s,a0,a1;
while (~scanf("%d",&n))
{
top=a0=a1=0;
memset(h,1,sizeof(int)*(n+2));
memset(v,1,sizeof(int)*(n+2));
memset(head,-1,sizeof(int)*(n+2));
for (int i=1;i<=n;i++) scanf("%d",&w[i]);
while (scanf("%d %d",&s,&p)&&(p+s))
{
h[s]=0;
add(p,s,top++);
}
for (int i=1;i<=n;i++)
{
if (h[i])
{
dfs(i);
a0+=dp[0];
a1+=Max(dp[0],dp[1]);
}
}
printf("%d\n",a0>a1?a0:a1);
}
return 0;
}