不是什么难题,但也算自己写的第一个树形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; }
时间: 2024-11-05 14:40:53