解题思路:树形DP;
状态转移方程:f[u][0]=f[u][0]+max(f[v][1],f[v][0]); //此上司选的情况
f[u][1]=max(f[u][1],f[v][0]+f[u][1]); //不选的情况
注意只有一个点的时候的情况。
输入的时候 注意每行输入一对整数L,K。表示K是L的直接上司;
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 10000
using namespace std;
struct node
{
int to,next;
}Map[maxn];
int p=0,head[maxn],parent[maxn],f[maxn][2];
void add(int x,int y)
{
p++;
Map[p].to=y;
Map[p].next=head[x];
head[x]=p;
}
int num[maxn];
int visit[maxn];
int ans=-1;
bool pp=0;
int dfs(int x)
{
visit[x]=1;
for(int k=head[x];k;k=Map[k].next)
{
if(!visit[Map[k].to])
{
dfs(Map[k].to);
}
f[x][0]=f[x][0]+max(f[Map[k].to][1],f[Map[k].to][0]);
f[x][1]=max(f[x][1],f[x][1]+f[Map[k].to][0]);
pp=1;
ans=max(ans,max(f[x][0],f[x][1]));
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
int a,b;
while(scanf("%d%d",&a,&b)&&a&&b)
{
add(b,a);
}
for(int i=1;i<=n;i++) f[i][1]=num[i];
for(int i=1;i<=n;i++)
{
if(!visit[i])
{
dfs(i);
}
}
if(pp) printf("%d",ans);
else printf("%d",num[1]);
return 0;
}