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;
}
posted @ 2021-07-14 19:30  BFNewdawn  阅读(21)  评论(0编辑  收藏  举报