CF1830A Copil Copac Draws Trees

传送门

题目思路

我们容易想到:如果当前边在输入中的顺序比父节点到祖父节点的边的顺序更早,那么这条边必须在下一轮才能被添加。

根据这个思路,我们需要的转移条件有每个点的父节点每条边被加入的时间

对于处理父节点和子节点的关系,可以想到 dfs 遍历整个树。每条边被加入的时间可以在输入时记录。

\(u\)\(v\) 的父节点,\(fa\)\(u\) 的父节点,边 \((u,v)\) 的加入时间是 \(id\),边 \((fat,u)\) 的加入时间是 \(pre\)

状态转移为 \(dp_v = dp_u + [id < pre]\)

注意操作是从第 \(1\) 轮开始,所以最终答案要加一。

输出 \(\max(dp[2], dp[3], \ldots, dp[n]) + 1\) 即可。

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,x[N],y[N];
vector<pair<int,int> >g[N];
int dfs(int u,int fa,int pre){
	int res=0;
	for(auto tmp:g[u]){
		int v=tmp.first,id=tmp.second;
		if(v!=fa){
			res=max(res,dfs(v,u,id)+(id<pre));
		}
	}
	return res;
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)	g[i].clear();
	for(int i=1,u,v;i<n;i++){
		cin>>u>>v;
		g[u].push_back({v,i});
		g[v].push_back({u,i});
	}
	cout<<dfs(1,0,0)+1<<"\n";
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int t;cin>>t;
	while(t--)	solve();
	return 0;
}
posted @ 2025-08-24 11:30  深申  阅读(9)  评论(0)    收藏  举报