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;
}

浙公网安备 33010602011771号