不是什么难题,但也算自己写的第一个树形DP,留个纪念吧= =
状态方程(dp[0][i]代表不选i人参加聚会时候的最大值,dp[1][i]代表选)
dp[0][pos] = max(dp[0][pos],max(dp[0][e] + dp[0][pos],dp[1][e] + dp[0][pos]));
dp[1][pos] = max(dp[1][pos],dp[1][pos] + dp[0][e]);
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 6005;
int n;
int v[maxn];
int vis[maxn];
int dp[2][maxn];
vector<int>G[maxn];
void dfs(int pos){
if(!G[pos].size()){
dp[0][pos] = 0;
dp[1][pos] = v[pos];
return;
}
dp[0][pos] = 0;
dp[1][pos] = v[pos];
for(int i = 0; i < G[pos].size(); i++){
int e = G[pos][i];
dfs(e);
dp[0][pos] = max(dp[0][pos],max(dp[0][e] + dp[0][pos],dp[1][e] + dp[0][pos]));
dp[1][pos] = max(dp[1][pos],dp[1][pos] + dp[0][e]);
}
return;
}
int main(){
while(scanf("%d",&n) != EOF){
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 1; i <= n; i++)
scanf("%d",&v[i]);
int a,b;
while(scanf("%d%d",&a,&b)){
if(!a && !b) break;
G[b].push_back(a);
vis[a] = 1;
}
int s;
for(int i = 1; i <= n; i++)
if(!vis[i]){
s = i;
break;
}
dfs(s);
printf("%d\n",max(dp[0][s],dp[1][s]));
}
return 0;
}