CF1988D The Omnipotent Monster Killer*2000树形dp

\[\begin{flalign*} &题意:给定一棵带点权的树,每轮游戏开始会受到所有未删除节点权值和的伤害\\& 结束时可以删除任意个不相邻的节点,问删完所有点时收到的最小伤害和&\\& \\& 定义dp_{i,j}为第j轮删除i节点,子树i所产生的最小伤害\\& 初值为j*a_i,转移方程:f_{i,j}=f_{i,j}+\sum ^{}_{k!=j}min(f_{son_i,k})\\& 复杂度:O(N*颜色数上界)\\& 下面证明颜色数上界不超过logN\\& 考虑从叶子往上推,那么点i的颜色最小值为mex(color_{son_i})(此处主要指的是种类数)\\& 设f(T)为颜色数上界为T的最小子树大小\\& 那么有递推式:f(T)=1+\sum^{T-1}_{i=0}f(i),根据f(0)=1,可以推出:f(N)=2^N\\& 从而大小为N的树的颜色上界为log_2N \end{flalign*} \]

const int N=3e5+10;
int a[N];
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]; 
	}
	vector<vector<int>>g(n+1),dp(n+1,vector<int>(24));
	vector<int>pre,suf;
	for(int i=1;i<n;i++){
		int u,v; cin>>u>>v;
		g[u].push_back(v),g[v].push_back(u);
	}
	auto dfs=[&](auto self,int u,int fa)->void{
		for(int i=1;i<20;i++) dp[u][i]=i*a[u];
		dp[u][0]=dp[u][20]=1e18;
		for(auto v:g[u]){
			if(v==fa) continue;
			self(self,v,u);
			for(int i=1;i<20;i++){
				dp[u][i]+=min(pre[i-1],suf[i+1]);
			}
		}
		pre=suf=dp[u];
		for(int i=1;i<20;i++){
			pre[i]=min(pre[i-1],dp[u][i]);
		}
		for(int i=19;i>=1;i--){
			suf[i]=min(suf[i+1],dp[u][i]);
		}
	};
	dfs(dfs,1,0);
	int ans=1e18;
	for(int i=1;i<20;i++) ans=min(ans,dp[1][i]);
	cout<<ans<<endl;
}
posted @ 2025-04-02 18:54  肆惠  阅读(14)  评论(0)    收藏  举报