黑白樹-----------------------------------------------樹形dp

在這裏插入圖片描述
在這裏插入圖片描述
解析:
染色肯定自下往上染,所以我們要從葉子結點開始染色。
先看子樹裏的點能不能染到這個點,染不到就++ans,把這個點的k傳上去
能染到的話要更新父節點的染色值(因爲有可能兒子節點染色值大於本身,這會讓答案更優)

染色值往上傳遞是要-1的
遞推方程 k[fa]=max(k[fa],k[u]-1)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10000;
vector<int> G[N];
int father[N];
int k[N],n,u;
int dfs(int u,int fa,int &ans)
{
	father[u]=fa;
	int now=0;
	for(auto j : G[u])
	{
		if(j==fa) continue;
		now=max(now,dfs(j,u,ans));
	}
	if(now<=1)
	{
		ans++;
		return k[u];
	}
	k[fa]=max(k[fa],k[u]-1);
	return now-1;
}
int main()
{
	while(~scanf("%d",&n))
	{
		int ans=0; 
		for(int i=1;i<=n;i++) G[i].clear();
	for(int i=2;i<=n;i++)
	{
		scanf("%d",&u);
  		G[i].push_back(u);G[u].push_back(i);	
	}
	for(int i=1;i<=n;i++) scanf("%d",&k[i]);
	dfs(1,0,ans);
	cout<<ans<<endl;
	} 
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章