树形dp 没有上司的舞会 P1352
题目大意:给定一棵树,两两相连的点不可同时选中,求可以选中的点的最大权值和
分析:典型树形dp,发现对于每一个父亲,自己选儿子一定不选,自己不选儿子可以选也可以不选;
树形结构,直接寻找根节点开始dp
状态:dp[x][1/0]表示选没选中:
dp[x][1]+=dp[y][0]
dp[x][0]+=max(dp[y][0],dp[y][1]);
以上:
#include <stdio.h> #include <algorithm> #include <cstring> #include <vector> using namespace std; const int maxn=20000; vector<int> son[maxn]; int n,rt; int h[maxn],vis[maxn],f[maxn][2]; inline void dp(int x) { f[x][1]=h[x]; f[x][0]=0; for(int i=0;i<son[x].size();i++) { int v=son[x][i]; dp(v); f[x][1]+=f[v][0]; f[x][0]+=max(f[v][1],f[v][0]); } return; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&h[i]); for(int i=1;i<=n-1;i++) { int u,v; scanf("%d%d",&u,&v); son[v].push_back(u); vis[u]=1; } for(int i=1;i<=n;i++) if(!vis[i]){ rt=i; break; } dp(rt); printf("%d",max(f[rt][0],f[rt][1])); return 0; }
浙公网安备 33010602011771号