其他分享
首页 > 其他分享> > 舞会(lgP1352)

舞会(lgP1352)

作者:互联网

写了一个多小时,本来觉得 bfs 能过然后码了好久发现不会确定顺序,又重新写了一遍 dfs /kk

好吧其实是因为我记得上次做这题的时候写的是 bfs

设 \(f[i][0]\) 表示以 \(i\) 为根的子树当 \(i\) 不去时的最大搞笑值, \(f[i][1]\) 表示以 \(i\) 为根的子树当 \(i\) 去时的最大搞笑值。

显然当 \(i\) 去的时候它的所有下属一定都不去,当 \(i\) 不去的时候它的下属可能去也可能不去。因此得到状态转移方程:

\(f[x][0]+=max(f[tr[x][i]][0],f[tr[x][i]][1])\) ;

\(f[x][1]+=f[tr[x][i]][0]\) 。

对于整棵树从根开始一遍 dfs 一边转移即可。

#include<bits/stdc++.h>
using namespace std;
vector<int>tr[5001];
int n,a[5001];
int f[5001][2];
void dp(int x)
{
 	f[x][0]=0;
 	f[x][1]=a[x];
 	for(int i=0;i<tr[x].size();i++)
 	{
  		dp(tr[x][i]);
 		f[x][0]+=max(f[tr[x][i]][0],f[tr[x][i]][1]);
		f[x][1]+=f[tr[x][i]][0];
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<n;i++)
	{
		int x;
		scanf("%d",&x);
		tr[x].push_back(i+1);
	}
	dp(1);
	cout<<max(f[1][0],f[1][1])<<endl;
	return 0;
}

qwq

标签:舞会,子树当,int,tr,5001,dfs,lgP1352,为根
来源: https://www.cnblogs.com/ying-xue/p/wu-hui.html