专栏文章

题解:AT_abc394_f [ABC394F] Alkane

AT_abc394_f题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq4ret1
此快照首次捕获于
2025/12/03 22:56
3 个月前
此快照最后确认于
2025/12/03 22:56
3 个月前
查看原文

思路

这道题是一个树形 DPDP

状态

dpu,idp_{u,i} 为以 uu 为根节点,有 ii 个子节点,最大节点个数。因为最多只能有四个,所以不会炸。

初始化

dpu,0dp_{u,0}11 就是它本身。其它的就为无穷小。

转移方程

dpu,i=max(dpu,i,dpu,i1+max(dpv,0,dpv,3))dp_{u,i}=max(dp_{u,i},dp_{u,i-1}+max(dp_{v,0},dp_{v,3}))
也就是说它可以选择加这个儿子或不加。要加的话就必须从儿子有三个或零个子节点中选,不然就不满足要求。由此可以推出此方程

Code

CPP
#include<bits/stdc++.h>
using namespace std;
int n,h[414514],e[414514],ne[414514],idx,dp[414514][5],mx=-1;
void add(int u,int v){
	e[idx]=v,ne[idx]=h[u],h[u]=idx++;
} 
void dfs(int u,int pre){
	dp[u][1]=-0x3f3f3f3f,dp[u][2]=-0x3f3f3f3f,dp[u][3]=-0x3f3f3f3f,dp[u][4]=-0x3f3f3f3f;
	dp[u][0]=1;
	for(int i=h[u];~i;i=ne[i]){
		int j=e[i];
		if(j==pre){
			continue;
		}
		dfs(j,u);
		for(int i=4;i>=1;i--){
			dp[u][i]=max(dp[u][i],dp[u][i-1]+max(dp[j][0],dp[j][3]));
		}
	}
	if(dp[u][1]>2){
		mx=max(mx,dp[u][1]);
	} 
	mx=max(mx,dp[u][4]);
}
int main(){
	memset(h,-1,sizeof(h));
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	dfs(1,0);
	cout<<mx;
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...