没有上司的舞会
-
核心思想: 树形dp
-
状态表示: f[u][0] 表示不选u点的最大方案 f[u][1]表示选u点的最大方案
-
状态计算: f[u][0] = max(f[j][1] , f[j][0]) j为u的子节点 因为不选u 所以j可取可不取
- f[u][1] = happy[u] + f[j][0] j为u的子节点 因为选u 所以j不能取
-
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N = 6010; int f[N][2]; bool has_father[N]; //找到根节点 int happy[N]; //快乐指数 int e[N],ne[N],h[N],idx; //邻接表 int n; void add(int a,int b) { e[idx] = b , ne[idx] = h[a] , h[a] = idx++; } void dfs(int u) { f[u][1] = happy[u]; //选u点 初值happy[u] for(int i = h[u] ; i!=-1;i=ne[i]) //找子节点 { int j = e[i]; dfs(j); //递归遍历 f[u][0] += max(f[j][0] , f[j][1]); f[u][1] += f[j][0]; } } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>happy[i]; memset(h,-1,sizeof h); for(int i=0;i<n-1;i++) { int a,b; cin>>a>>b; add(b,a); //b是a的父节点 has_father[a] = true; //a有父节点 } int root = 1; while(has_father[root]) root ++; //有父节点就++ 找到根节点序号 dfs(root); cout<<max(f[root][1] , f[root][0]); //选/不选根节点的最大方案 }
-