https://codeforces.com/contest/1453/problem/E
感觉E比D简单。。。流下了经典想不清期望的泪水.jpg
观察发现如果当到了u,选择一个子节点v1,一定会把那棵子树v1吃光,才能穿过u去另一个子树v2
dp[u]表示吃完u的子树,最后能停的最小深度
然后对于每个不是1的根节点,他肯定要从某个儿子所在的子树的dp[v],跳到另一个儿子节点,那么这个距离最少就是dp[v]-dep[u]+1,每个这个跳的距离都更新一下ans
然后1为根节点的时候特判一下,因为可以找个dp[v]最大的子树然后直接回到1结束
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,k,cnt,tot,cas,ans;
int a[maxl],dep[maxl],dp[maxl];
bool vis[maxl];
char s[maxl];
vector<int> e[maxl],midep[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
e[i].clear();
for(int i=1;i<=n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
}
inline void dfs(int u,int fa)
{
midep[u].clear();
for(int v:e[u])
if(v!=fa)
{
dep[v]=dep[u]+1;
dfs(v,u);
midep[u].push_back(dp[v]);
}
sort(midep[u].begin(),midep[u].end());
int l=midep[u].size();
if(!l)
dp[u]=dep[u];
else if(l==1)
dp[u]=midep[u][0];
else
{
if(u>1)
{
dp[u]=midep[u][0];
ans=max(ans,midep[u][l-1]-dep[u]+1);
}
}
if(u==1 && l>0)
ans=max(ans,midep[u][l-1]-dep[1]);
if(u==1 && l>1)
ans=max(ans,midep[u][l-2]-dep[1]+1);
}
inline void mainwork()
{
ans=0;dep[1]=1;
dfs(1,0);
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}