Catch You Catch Me
https://codeforces.com/gym/104065/problem/C
对于第一个样例的解释:
由于2和5两个节点下一步就要到出口,所以0分钟要同时收集2和5两只蝴蝶,否则下一分钟蝴蝶飞走,操作次数为2
对于3,4节点而言,在进行完收集2和5之后,3和4节点的蝴蝶跑到了2节点去,此时就只需操作一次就可以同时收集两只蝴蝶
而实现最小化操作就是对于父节点带节点的情况只需先收集父节点,子节点汇聚后在收集即可(带两子节点可优化,1个字节点本身就是最优)
题目理解:
蝴蝶每分钟都会向上移动一步等同于对于树中的任何节点,其所有子节点上的蝴蝶最终都会汇聚到该父节点上(或更上面的节点上)。
也就是说我们最终只需要考虑子树的深度即可
所以就可以将题目转化为:父节点1的所有子树深度之和
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
vector<int> g[n+1];
for(int i=1;i<n;i++){
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
//一个lambda表达式
function<int(int,int,int)> dfs = [&](int cur,int fa,int dep) -> int{
if(g[cur].size()==1){
return dep;
}
int maxdep=0;
for(auto & e : g[cur]){
if(e!=fa){
maxdep = max(maxdep,dfs(e,cur,dep+1));
}
}
return maxdep;
};
int ans=0;
for(auto& e:g[1]){
ans+=dfs(e,1,1);
}
cout<<ans;
}