专栏文章

题解:CF1830A Copil Copac Draws Trees

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

文章操作

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

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

树形DP

由于本题的树是一颗有根树,在构建完这颗以 11 为根的树后不难发现:一个点 uu 的父边与这个点 uu 的父结点 fatherufather_u 的父边之间显然存在顺序关系(因为在有根树中,一个点的父节点是唯一确定的)。
具体地说,如果点 uu 的父边对应的编号大于点 fatherufather_u 的父边编号,则说明这两条边都可以在同一次步骤一中添加。反之则点 uu 的父边需要在点 fatherufather_u 的父边构建完后执行下一次步骤一时构建。
于是可以对输入的每条边记录按顺序编号,然后对图中的每个点进行 DP。
fif_i 表示 ii 结点的父边是在第几次操作一中构建的。
vv 的父节点为 uuvv 的父边编号为 ididuu 的父边编号为 pre_idpre\_id,此时转移显然:
fv=fu+[id<pre_id]f_v=f_{u} + [id<pre\_id]
注意初始化 f1=1f_1=1,最后答案即为 maxi=1nfi\max_{i=1}^n f_i
CPP
#define rep(x,y,z) for(int x=y;x<=z;x++)
const int N=2e5+5;
int n;
vector<array<int,2>> E[N];
int f[N];
void dfs(int u,int father,int pre_id){
	for(auto t:E[u]){
		int v=t[0],id=t[1];
		if(v==father) continue;
		f[v]=f[u]+(id<pre_id);
		dfs(v,u,id);
	}
}
void solve(){
	cin>>n;
	rep(i,1,n) E[i].clear();
	rep(i,1,n-1){
		int a,b;
		cin>>a>>b;
		E[a].push_back({b,i});
		E[b].push_back({a,i});
	}
	dfs(1,-1,0);
	int ans=0;
	rep(i,1,n) ans=max(ans,f[i]);
	cout<<ans+1;
}

评论

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

正在加载评论...