P1352 没有上司的舞会 题解
0x01 读题
\(……\)
0x02 分析
题中指出了给出的关系是树,相互有依赖关系,又让最大值,本题思路可知是 \(bfs\) 和记忆化搜索
可惜本蒟蒻不会记忆化搜索 \(qwq\)
您应该清楚,任何记忆化搜索都可以写成 \(dp\) ,(只是不同的题写法的简便程度不同),所以我们又可以想到树状 \(dp\ !\)
一种是\(A\)君来,\(ta\)的部下不来的指数,用\(1\)表示;一种是\(A\)君不来,\(ta\)的部下来的指数,用\(0\)表示;
0x03 状态转移方程
\(f[x][1]=max(max(f[x][1],f[x][1]+f[i][0]),f[i][0]);\)
\(f[x][0]=max(max(f[x][0],f[i][1]+f[x][0]),max(f[i][1],f[i][0]));\)
0x04 \(Code\)
#include<bits/stdc++.h>
using namespace std;
const int N=6010;
int n,root;
int f[N][2];
struct tree{
int rt,up,dn;
}t[N];
void work(int x){
for(int i=t[x].dn;i;i=t[i].up){
work(i);
f[x][1]=max(max(f[x][1],f[x][1]+f[i][0]),f[i][0]);
f[x][0]=max(max(f[x][0],f[i][1]+f[x][0]),max(f[i][1],f[i][0]));
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&f[i][1]);
for(int i=1;i<=n-1;i++){
int l,k;
scanf("%d%d",&l,&k);
t[l].rt++;
t[l].up=t[k].dn;
t[k].dn=l;
}
for(int i=1;i<=n;i++){
if(t[i].rt==0){
root=i;
break;
}
}
work(root);
cout<<max(f[root][0],f[root][1]);
return 0;
}