CF1453E Dog Snacks 题解

Codeforces
Luogu

Description.

有个树,有一只嘉然小姐姐的狗,要去顿顿解馋。
树上每个节点有嘉然的视频,狗要遍历所有节点。
它刚开始在 \(1\),每次会找到最近的没走过的节点,然后跳过去,最后回到 \(1\)
如果有多个最近节点,狗可以选择。
要让狗每次跳的距离最大值尽可能小。

Solution.

考虑贪心,当前这个点决策如下:

  1. 跳到某个子树,往下跳
  2. 从这个子树跳到另一个子树,迭代
  3. 从这个子树跳会它上面

然后记 \(f_u\) 表示从这个子树跳到上面的最小步数。
那肯定有 \(f_u=\min_{v\in\text{son}(u)}(f_v)+1\)
决策肯定是当前最小的留到最后。
所以每次要跳一个最大值 \(+1\)
如果是根,最大值是不需要 \(+1\) 的,因为最后要回到 \(1\)
然后就做完了???

Coding

点击查看代码
//Coded by Kamiyama_Shiki on 2021.10.31 {{{
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
const int N=200005;
struct edge{int to,nxt;}e[N<<1];int et,head[N],dg[N],n,rs;
inline void adde(int x,int y) {e[++et]=(edge){y,head[x]},head[x]=et,dg[x]++;}
inline int dfs(int x,int fa)
{
	vector<int>v;for(int i=head[x];i;i=e[i].nxt)
		if(e[i].to!=fa) v.push_back(dfs(e[i].to,x));
	sort(v.begin(),v.end());
	if(v.empty()) return 1;else rs=max(rs,v[0]);
	if(v.size()==1ull) return v[0]+1;
	if(fa) rs=max(rs,v.back()+1);else rs=max(rs,max(v[v.size()-2]+1,v.back()));
	return v[0]+1;
}
inline void solve()
{
	read(n),et=0,memset(head,0,sizeof(head)),memset(dg,0,sizeof(dg));
	for(int i=1,x,y;i<n;i++) read(x,y),adde(x,y),adde(y,x);
	rs=0,dfs(1,0),printf("%d\n",rs);
}
int main() {int Ca;for(read(Ca);Ca--;) solve();return 0;}
原文地址:https://www.cnblogs.com/pealfrog/p/15492775.html